Search code examples
pythondynamicparameterssignatureinspect

How to dynamically add method to object while preserving the same signature?


I just want to copy all member variables and method of a object to another.

I use setattr() function for member variables and types.MethodType for method, but in this case, copied function has nothing in inspect.signature.

I want to copy the parameter list, too. How can I do that?

I make an example below:

import inspect

class source:
  def func1(self, a: str, b: int):
    print(a, "%d"%b)

class dest:
  pass

s = source()
d = dest()

# copy s -> d

inspect.signature(d.func1)
# -> Out: <Signature (a:str, b:int)>

Solution

  • Methods are attributes of the class to which they are bound and that is where inspect looks for them. This mean you must to copy them from the Source class to the Dest class. When you do it this way, they'll both automatically have the same signature of course.

    import inspect
    
    class Source:
        def func1(self, a: str, b: int):
            print(a, "%d"%b)
    
    class Dest:
        pass
    
    s = Source()
    d = Dest()
    
    print(inspect.signature(s.func1))  # -> (self, a: str, b: int)
    setattr(type(d), 'func1', Source.func1)
    print(inspect.signature(d.func1))  # -> (self, a: str, b: int)
    d.func1('ans', 42)  # -> ans 42