2

假设我有一个类Foo。我写了一个装饰器deco,我想应用到 class 的一些方法上Foo。由于Foo是从库中导入的,因此我决定将其子类化为Bar. 现在,我唯一需要做的就是将装饰器添加到Foo.

class Bar(Foo):

    @deco
    def aMethod(self, *args, **kwargs):
        super().aMethod(*args, **kwargs)

由于我不需要修改 的代码aMethod,有没有更简单的方法来装饰它,而无需显式调用super()

4

2 回答 2

5

您可以Foo通过将方法替换为修饰版本来进行猴子补丁:

Foo.aMethod = deco(Foo.aMethod)

装饰器语法只是语法糖,毕竟deco只是一个可调用的,其结果替换了装饰函数:

@deco
def aMethod(...):
    ....

有效地翻译为:

def aMethod(....):
    ...
aMethod = deco(aMethod)

或者,如果您更喜欢仍然使用子类,请在类的主体中执行相同的操作:

class Bar(Foo):
    aMethod = deco(Foo.aMethod)

在 Python 2 中,您需要先解包函数:

Foo.aMethod = deco(Foo.aMethod.im_func)
于 2013-05-28T20:11:47.127 回答
0

你可以这样做:

class Bar(Foo):

    aMethod = deco(Foo.aMethod)   # Foo.aMethod.im_func in Py2.x

但是,您将失去super(); 你本质上是在那个时候“修复”父类,而不是等到运行时找到它。不过,这在多继承场景之外可能没问题。

于 2013-05-28T20:11:57.660 回答