简体   繁体   中英

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. 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. 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. 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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