【问题标题】:Use method from superclass as "decorator" for subclass使用超类中的方法作为子类的“装饰器”
【发布时间】:2019-12-03 11:51:22
【问题描述】:

我有一个场景,我想在 python 的子类中“标记”方法,基本上是说“将此子类方法包装在超类中的方法中”

例如:

class SuperClass:
    ...
    def wrapping_method(func):
        # do something in the SuperClass instance before the method call
        func(args)
        # do something in the SuperClass instance after the method call
    ...

class SubClass(SuperClass):
    ...
    def my_function(args):
        # do something in the SubClass instance
    ...

我希望这样每当我在 SubClass 中调用 my_function(args) 时,SuperClass 中的 wrapping_method() 会被调用,而方法 my_function 作为参数传入(所有 my_function 参数都以某种方式)。

我不熟悉如何在这里使用装饰器之类的东西,但我希望能够使用某种类似注释的“@”符号来“标记”子类方法。

【问题讨论】:

  • 您尝试了哪些方法,遇到了哪些问题?装饰器和继承是正交的。您可以直接用超类方法装饰子类方法(注意它应该是一个类方法),例如@SuperClass.wrapping_method def my_function(self, args): ...
  • 请说明您想做什么。您的新代码 cmets(对实例进行操作)与您的描述(对类进行操作)冲突。当您有特定的 SubClass 实例时,通常没有特定的 SuperClass 实例,反之亦然。
  • 在超类中,我想在子类中对my_function 的方法调用前后更新字段。我只是用实例这个词来表示在 SuperClass 构造函数中声明的字段正在被更新。

标签: python python-3.x inheritance


【解决方案1】:

使用装饰器和子类化是正交的。您可以在基类方法(或您喜欢的任何地方)中定义装饰器,并将其应用于子类方法(或您喜欢的任何地方)。

class SuperClass:
    """Type that counts invocation of methods decorated with @counted"""
    def __init__(self):
        self.count = 0

    # define decorator by taking one callable as argument
    @staticmethod
    def counted(method):  # 1
        """Decorate a method to count its invocations"""
        def counted_method(self, *args, **kwargs):
            self.count += 1
            bound_method = method.__get__(type(self), self)  # 2
            return bound_method(*args, **kwargs)
        return counted_method

class SubClass(SuperClass):
    # use `@decorator` to decorate a method
    @SuperClass.counted
    def my_method(self):
        print("doing something in the SubClass instance")

这里,counted 是一个普通的装饰器,这意味着它只需要一些可调用的 (#1) 并对其执行 some 操作——在本例中,包装它。由于counted_method 包裹了实际的方法,我们必须manually invoke the descriptor protocol (#2) 来模拟方法查找。

>>> instance = SubClass()
>>> instance.count
0
>>> instance.my_method()
doing something in the SubClass instance
>>> instance.count
1

【讨论】:

    猜你喜欢
    • 2016-10-14
    • 2021-02-12
    • 2019-11-27
    • 2016-12-31
    • 2014-02-18
    • 2021-04-12
    • 2018-08-15
    • 2014-01-14
    • 2017-07-28
    相关资源
    最近更新 更多