Search code examples
pythonclassoopdecorator

Python: How do you decorate methods in child classes using a method in the parent class?


code example:

class Parent:
    # something here that says that the function "foo" always starts in print("bar")

class Son(Parent):
    def foo(self):
        pass

class Daughter(Parent):
    def foo(self):
        print("q")


Son().foo() # prints "bar"
Daughter().foo() # prints "bar" then "q"

i tried to use @super.func though it's shoddy to copy paste that in every class that has Parent as the parent and has the foo method. any elegant solutions?


Solution

  • There may be more elegant methods, but you can decorate the methods of the subclasses in the __init_subclass__ hook

    def bar_printer(f):
        def wrapper(*args, **kwargs):
            print('bar')
            return f(*args, **kwargs)
    
        return wrapper
    
    
    class Parent:
    
        def foo(self):
            pass
    
        def __init_subclass__(cls, **kwargs):
            cls.foo = bar_printer(cls.foo)
    
    
    class Son(Parent):
        def foo(self):
            pass
    
    
    class Daughter(Parent):
        def foo(self):
            print("q")
    
    son = Son()
    daughter = Daughter()
    
    son.foo()
    daughter.foo()
    

    Output:

    bar
    bar
    q