从派生类向其基类添加装饰器的最简洁方法是什么?

时间:2013-09-25 17:44:48

标签: python class python-decorators

我有一组共享大部分功能的不同类。它们的差异可以在单个方法中分离,在装饰器中可以应用于其中一个基本方法。

设置此装饰器的派生类最干净的是什么,它必须应用于基类方法?我沿着这些方向尝试了一些东西,但它没有用,因为要装饰的方法已经绑定了:

class Base(other):
    decorator = lambda x:x

    def __init__(self, *args, **kwargs):
        self.post = self.decorator(self.post)
        super(Base, self).__init__(*args, **kwargs)

    def post(self):
        pass

class Derived(Base):
    decorator = some_decorator

1 个答案:

答案 0 :(得分:1)

简短版本是:你想要的东西与静态方法实际上是一样的,这是解决它的最简单方法。


问题不在于方法self.post是绑定的,而是装饰器self.decorator是。

将函数存储为类属性时,这与定义新方法基本相同。因此,以self.decorator访问它将获得绑定方法。 (如果你不明白为什么,要么阅读Descriptor HowTo,要么信仰它。)这意味着它将以self为第一个参数进行调用。

您总是可以向self添加一个明确的decorator参数,然后忽略它......但如果您想要一个没有self参数的方法,那么这就是静态方法:当用作方法时,不会采用魔法self。所以:

class Derived(Base):
    @staticmethod
    def decorator(func):
        whatever(fund)

......或:

class Derived(Base):
    decorator = staticmethod(whatever)

如果你真的想查找decorator作为数据属性,即使它是一个函数,简单的方法是将它移动到实例:

class Derived(Base):
    def __init__(self, *args, **kwargs):
        self.decorator = whatever
        super(Derived, self).__init__(*args, **kwargs)

或者,当然,您可以改变描述方法性:

self.post = self.decorator.im_func(self.post)

...或者通过手动执行查找来避免它:

decorator = type(self).__dict__['decorator']
self.post = decorator(self.post)

这些都是hacky,但是你正在尝试做一些hacky,所以我不认为这是一个hackiness明确的问题。