【问题标题】:What's the cleanest way to add a decorator from a derived class to its base class?将派生类中的装饰器添加到其基类的最简洁方法是什么?
【发布时间】:2013-10-01 10:44:01
【问题描述】:

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

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

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

【问题讨论】:

  • 你的问题不是很清楚。它以什么方式不起作用?你能举例说明你想要发生的事情吗?你是说派生类应该继承基类方法,但装饰器不同?
  • 派生类用于从基类继承东西,而您正试图做其他方式。
  • @hcwhsa:他试图覆盖基类的行为,这在子类中是完全合理的。这不是最常见的方式,但也不落后。

标签: python class python-decorators


【解决方案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是明确的问题。

【讨论】:

    猜你喜欢
    • 2019-05-02
    • 2010-11-23
    • 2017-03-24
    • 1970-01-01
    • 2019-10-09
    • 1970-01-01
    • 1970-01-01
    • 2018-10-26
    • 2015-08-08
    相关资源
    最近更新 更多