如何在基类的函数上使用装饰器并在继承基类时让装饰器在该函数上工作

Posted

技术标签:

【中文标题】如何在基类的函数上使用装饰器并在继承基类时让装饰器在该函数上工作【英文标题】:How to use decorators on a function of a Base Class and have the decorator work on that function when the Base Class is inherited 【发布时间】:2019-01-18 21:57:26 【问题描述】:

我有一个基类Example 和一个抽象方法example。我想在example 函数上添加另一个装饰器,我在下面做了 - 装饰器是@foo

当我使用这个基础 Example 类创建新类时,我创建了一个适当的 example 函数,@foo 应该做什么,最终不会起作用。

我认为问题在于,当我在新类上创建 example 函数时,它被“覆盖”了。

from abc import ABCMeta, abstractmethod

class Example(object):
    __metaclass__ = ABCMeta

    def __init__(self):
        self.num = 0

    @abstractmethod
    @foo
    def example(self, output):
        pass

class ExampleSum(Example):
    def example(self, output):
        self.num = self.num + output

有什么指导吗?基本上,我希望 @foo 行为出现在 ExampleSumexample 函数中,而无需显式编码。

【问题讨论】:

【参考方案1】:

我认为问题在于,当我创建 新类的示例函数。

你是绝对正确的:装饰方法被覆盖。但是如果你只抽象example的“内部部分”,你就可以实现你的目标:

from abc import ABCMeta, abstractmethod

class Example(object):
    __metaclass__ = ABCMeta

    def __init__(self):
        self.num = 0

    @foo
    def example(self, output):
        return self._example_impl(output)

    @abstractmethod
    def _example_impl(self, output):
        pass

class ExampleSum(Example):
    def _example_impl(self, output):
        self.num = self.num + output

【讨论】:

以上是关于如何在基类的函数上使用装饰器并在继承基类时让装饰器在该函数上工作的主要内容,如果未能解决你的问题,请参考以下文章

作为基类一部分的 Python 装饰器不能用于装饰继承类中的成员函数

装饰类的继承类方法中的 cls 行为

使用基类装饰器扩展组件装饰器

Python:强制装饰器继承?

对虚函数进行重载是啥意思?

使用装饰器作为类来装饰 Python 类