简体   繁体   English

如何在 Python 中为父类的每个子类的方法分配装饰器

[英]How to assign a decorator to a method of each child class of a parent class, in Python

I have a Parent class and many subclasses extend it.我有一个 Parent 类,许多子类都扩展了它。 I overwrite a method of parent class at each subclass.我在每个子类中覆盖了父类的方法。 But I don't want to lose the decorator that the method overridden.但我不想丢失该方法覆盖的装饰器。 Here is an example:下面是一个例子:

class Parent:
  @decorator
  def a_method(self):
    print('Parent class a_method')

class Sub1(Parent):
  def a_method(self):
    print('Sub1 class a_method')

class Sub2(Parent):
  def a_method(self):
    print('Sub2 class a_method')
  
class Sub3(Parent):
  def a_method(self):
    print('Sub3 class a_method')

s1 = Sub1()
s1.a_method() # doesn't run @decorator

I need the decorator to be reflected in the a_method of each subclass.我需要装饰器反映在每个子类的a_method中。 In other words, I want to run the same logic before and after a_method invoked and don't want to write it again and again in each subclass.换句话说,我想在调用a_method之前和之后运行相同的逻辑,并且不想在每个子类中一次又一次地编写它。 How to achieve this?如何实现这一目标? And what would be the best way to realize it?实现它的最佳方式是什么? This doesn't need to be a decorator but It would be nice and more cleaner.这不需要是装饰器,但它会更好更干净。

Thanks!谢谢!

Basically a metaclass would be perhaps appropriate here, in order to decorate the relevant method inside the __new__ method during class creation.基本上, metaclass在这里可能是合适的,以便在类创建期间装饰__new__方法内的相关方法。

def decorator(f):
    def wrapper(*args):
        print('decorator fired!!!')
        return f(*args)

    return wrapper


class MetaClass(type):
    def __new__(cls, clsname, bases, attrs):
        if 'a_method' in attrs:
            attrs['a_method'] = decorator(attrs['a_method'])
        return type.__new__(cls, clsname, bases, attrs)


class Parent(metaclass=MetaClass):
    def a_method(self):
        print('Parent class a_method')


class Sub1(Parent):
    def a_method(self):
        print('Sub1 class a_method')

    def k_method(self):
        print('Sub1 class k_method')


p1 = Parent()
p1.a_method()
print("-------------------------------")
s1 = Sub1()
s1.a_method()

# decorator fired!!!
# Parent class a_method
# -------------------------------
# decorator fired!!!
# Sub1 class a_method

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

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