如何在保留相同签名的同时动态地向对象添加方法?

问题描述

我只想将一个对象的所有成员变量和方法复制到另一个

我对成员变量使用 setattr() 函数,对方法使用 types.MethodType, 但在这种情况下,复制的函数inspect.signature 中没有任何内容

我也想复制参数列表。我该怎么做?

我在下面举个例子:

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)>

解决方法

方法是它们绑定到的 class 的属性,这就是 inspect 寻找它们的地方。这意味着您必须将它们从 Source class 复制到 Dest class。当您这样做时,它们当然会自动具有相同的签名。

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,b: int)
setattr(type(d),'func1',Source.func1)
print(inspect.signature(d.func1))  # -> (self,b: int)
d.func1('ans',42)  # -> ans 42