如何从修饰的子类方法中调用重写的超类方法

jbhunt:

我正在尝试创建一个装饰器,当子类重写该方法时,该装饰器将扩展类方法的功能。这是一个最小的示例:

class Parent(object):
    def __init__(self):
        return

    def say_hello(self):
        print('Parent says hello')

class Child1(Parent):
    def __init__(self):
        super().__init__()

    def say_hello(self):
        print('Child says hello')

child = Child1()
child.say_hello() # this will print 'Child says hello'

我想创建一个装饰器,该装饰器除了执行孩子的方法外,还将执行父方法。

def extendedmethod(method):
    def wrapper(obj):
        # call the method as defined by the superclass
        method(obj) # call the method defined by the subclass
    return wrapper

class Child2(Parent):
    def __init__(self):
        super().__init__()

    @extendedmethod
    def say_hello(self):
        print('Child says hello')

child = Child2()
child.say_hello() # I want this to print 'Parent says hello' then 'Child says hello'

我想我真正要问的是如何访问装饰器内部派生子类的超类?

宫城先生:

在显式代码中,我们将编写以下内容:

class Child2(Parent):
    def say_hello(self):
        super().say_hello()  # call baseclass method
        print('Child says hello')

的无参数形式super()被编译到super(__class__, self)此处,其中__class__ = Child2重要的部分是super需要实例self拥有类。


获取实例很简单–调用时将其传递给修饰的方法。面临的挑战是提取装饰方法所在的类。

一种方法是我们的设计装饰的描述符(类似property) -描述符可以定义一个方法__set_name__来接收他们的名字和所属类另外,我们必须定义__get__满足描述符协议和receive self,以及__call__实际调用方法的方法:

class extendedmethod:
    """Decorator to call the superclass method before a method"""
    def __init__(self, method, owner=None):
        self.method = method
        self.owner = owner

    def __set_name__(self, owner, name):
        self.owner = owner

    def __get__(self, instance, owner=None):
        # self.__call__ with `__m_self__` and `__m_cls__` filled in
        return partial(self, instance, owner)

    def __call__(self, __m_self__, __m_cls__, *args, **kwargs):
        # self: the decorator instance
        # __m_self__: the `self` seen by a method
        # __m_cls__: the `cls` seen by a classmethod
        # super(__class__, self).say_hello ------------------------v 
        #      v super(__class__, self) ----v
        getattr(super(self.owner, __m_self__), self.method.__name__)(*args, **kwargs)
        return self.method.__get__(__m_self__, __m_cls__)(*args, **kwargs)

该装饰器可以直接应用于方法,以调用其超类方法:

class Child2(Parent):
    @extendedmethod
    def say_hello(self):
        print('Child says hello')

Child2().say_hello()
# Parent says hello
# Child says hello

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected].com 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何调用超类的重写方法?

为什么从子类的超类调用方法中获得“ this”?

从超类调用子类方法

Java:强制子类重写超类的方法

如何从子类中调用重写的父类方法?

从打字稿中的超类调用重写的方法

如何确保某些方法从子类(Java)中的方法从抽象超类中调用

调用超类方法而不是子类方法

在向量C ++中从超类调用子类方法

超类引用无法在Java中调用子类方法

调用在超类中重写的默认接口方法

Java继承:在超类中调用子类方法

确定用于调用子类中的方法的超类引用

Javascript ES6:如何从超类中定义的静态方法中检索调用子类

如何重写子类中的方法并调用父类方法而不丢失数据

Java:从超类构造函数中的子类调用的方法

如何使子类自动调用超类方法

在父类和子类的构造函数中调用重写的方法

Python-如何从子类实例调用超类的方法?

如何使用最终方法PHP防止子类重写超类

如何决定从父类或子类中调用子类中的重写方法?

您如何在Java中从超类调用子类方法?

当子类对象存储在超类数组中时,如何调用子类方法?

从超类对象数组中调用子类方法

如何从重写的子类方法调用超类的继承方法?

从 Java 中超类类型的 ArrayList 调用子类方法

如何使用子类的数据调用超类方法?

如何调用派生类(子类)的重写方法?

从父类调用子类的重写方法