Python,如何更改另一个类的方法';实例

Python,如何更改另一个类的方法';实例,python,class,Python,Class,我想给另一个类实例的方法添加一些小功能。 下面列出了我尝试的内容。用同样的方法,完全改变方法是可能的。但我想保留对原始方法稍加修改的版本。可能吗 顺便说一句:这些类不能相互继承,因为我不一定知道什么是类B class A: def alter_fn(self, obj): def wrapper(): func = getattr(obj, obj.fn_name) out = func() prin

我想给另一个类实例的方法添加一些小功能。 下面列出了我尝试的内容。用同样的方法,完全改变方法是可能的。但我想保留对原始方法稍加修改的版本。可能吗

顺便说一句:这些类不能相互继承,因为我不一定知道什么是类B

class A:
    def alter_fn(self, obj):
        def wrapper():
            func = getattr(obj, obj.fn_name)
            out = func()
            print('out = ', out)
            return out
        setattr(obj, obj.fn_name, wrapper)
        return

class B:
    def __init__(self) -> None:
        self.fn_name = 'fn'

    def fn(self):
        return 123


a=A()
b=B()

a.alter_fn(b)
b.fn()
由于明显的原因,这会引起递归深度错误,但我不知道如何避免。我还尝试了
func=copy(getattr(obj,obj.fn_name))


更改方法b.fn后,我希望它返回值,未更改的函数将返回(此处为123),但我也希望它对该输出执行其他操作,在本例中,将其打印。

func
的赋值移动到
包装器的定义上方

...
def alter_fn(self, obj):
    func = getattr(obj, obj.fn_name)
    def wrapper():
        ...

这样,
getattr
只被调用一次,
wrapper
可以作为闭包变量访问
func

func
的赋值移动到
wrapper
的定义之上

...
def alter_fn(self, obj):
    func = getattr(obj, obj.fn_name)
    def wrapper():
        ...

这样一来,
getattr
只被调用一次,而且
wrapper
可以作为闭包变量访问
func

只需将
func=getattr(obj,obj.fn_name)
wrapper
函数中取出即可

A类:
def alter_fn(自身、obj):
func=getattr(对象,对象.fn\u名称)
def包装器():
out=func()
打印('out=',out)
返回
setattr(obj,obj.fn_名称,包装器)
返回

您只需将
func=getattr(obj,obj.fn_name)
包装器中取出即可

A类:
def alter_fn(自身、obj):
func=getattr(对象,对象.fn\u名称)
def包装器():
out=func()
打印('out=',out)
返回
setattr(obj,obj.fn_名称,包装器)
返回

在重新分配函数之前,您需要获得包装函数:

def alter_fn(self, obj):
    func = getattr(obj, obj.fn_name)
    def wrapper():
        out = func()
        print('out = ', out)
        return out
    setattr(obj, obj.fn_name, wrapper)
    return
这样,在调用原始函数时,只分配一次
func
。因此,您可以安全地调用它,而无需再次意外调用
wrapper()


也可以考虑使用<代码>函数工具.WrpScript()/Case>来保持字符串的字符串和名称信息相同。

< p>在重新赋值之前需要得到包装函数:

def alter_fn(self, obj):
    func = getattr(obj, obj.fn_name)
    def wrapper():
        out = func()
        print('out = ', out)
        return out
    setattr(obj, obj.fn_name, wrapper)
    return
这样,在调用原始函数时,只分配一次
func
。因此,您可以安全地调用它,而无需再次意外调用
wrapper()


也考虑使用<代码>函数工具.WrpScript()/Case>来保持字符串的字符串和名称信息相同。

是的,现在很明显。大脑冻结了。谢谢,现在很明显了。大脑冻结了。谢谢汉克斯,你说得对。我选择了另一个答案,因为他快了一点(我希望如此)。谢谢,你说得对。我选择了另一个答案,因为他快了一点(我希望如此)。