繁体   English   中英

使用超类的方法作为子类的“装饰器”

[英]Use method from superclass as "decorator" for subclass

我有一个场景,我想在 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参数)。

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

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

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 )并对其执行一些操作——在这个例子中,包装它。 由于counted_method包含实际方法,我们必须手动调用描述符协议( #2 ) 来模拟方法查找。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM