【问题标题】:Inherit decorator defined in parent class继承父类中定义的装饰器
【发布时间】:2015-06-18 04:30:00
【问题描述】:

不要试图冗长地解释,这段代码sn-p应该这样做。

def decorator(function):
    return lambda self: function(self) + 1

# imported from library
class A(object):
    # override
    def method_1(self):
        pass

    # override
    def method_2(self):
        pass

class B(A):
    def method_1(self):
        return 1

class C(B):
    @decorator
    def method_2(self):
        return 1

class D(B):
    @decorator
    def method_2(self):
        return 2

print C().method_1() # 1
print C().method_2() # 2
print D().method_2() # 3

这很好用,但由于decorator 只在method_2 上使用,也许应该拉进去。

class B(A):
    def method_1(self):
        return 1

    @staticmethod
    def decorator(function):
        return lambda self: function(self) + 1

class C(B):
    @B.decorator
    def method_2(self):
        return 1

这可行,但我不清楚这是否真的更好。尤其是 Python 是否将B.decorator 视为恰好在B 上定义的外部 函数,或者如果C 继承自B 会更有效。

我真正想要的是在B 上定义装饰器并像这样在C 上使用它。

class C(B):
    @self.decorator
    def method_2(self):
        return 1

这不起作用。也许有更好的选择吗?谢谢。

【问题讨论】:

  • 我看不出有什么特别的理由将装饰器移到课堂上。在 Python 的类之外有辅助的东西是完全正常的。

标签: python python-2.7 python-decorators


【解决方案1】:

除了没有理由将装饰定义移到类内部,正如 cmets 中所指出的那样,还有一些说明:

当您在装饰器定义中使用 @staticmethod 装饰器时,您将拥有与在任何类主体之外定义完全相同的行为。

如果您确实使用@classmethod,如

 class B(A):

    @classmethod
    def decorator(cls, function):
        return lambda self: function(self) + 1

不同之处在于装饰器被传递给它定义的类,作为一个对象作为第一个参数。这可能有用,也可能没有用 - 请注意,装饰方法本身仍将是常规实例方法 - 除非您在装饰器主体内部使用 @classmethod@staticmethod 装饰器,更改它返回的包装器函数。

至于高效:最“高效”的事情是将装饰器留在任何类主体之外 - “@staticmethod”防御装饰器的差异将是最小的 - 可能根本无法测量,但应该涉及两个或在类创建时减少三个属性访问(通常不会在应用程序的关键循环内) - 所以,不,没有区别。

现在,这不是您要问的,但是有人可能会来这里寻找如何在子类中覆盖此方法时自动在超类中的方法中重新应用装饰器: 这并不容易,但应该可以使用专门准备的装饰器(它们会在包装方法上注释自己)

【讨论】:

    猜你喜欢
    • 2017-02-21
    • 1970-01-01
    • 2011-03-23
    • 2011-11-20
    • 2021-07-19
    • 2023-04-09
    • 2014-03-07
    • 2018-04-17
    • 2011-09-18
    相关资源
    最近更新 更多