How to decorate child method with parent method

Viewed 15

Can i decorate child methods with parent method where i extract some common code? The Design and structure of classes must be preserved. I have:

class Parent:

    def general_create(self, create_child_func):
        def wrapper(*args, **kwargs):
            print("Some general actions before")
            result = create_child_func(*args, **kwargs)
            print("Some general actions after")
            return result
        return wrapper


class A(Parent):
    def create(self):
        print("Сreate actions for class A")
        return "Result A"


class B(Parent):
    def create(self):
        print("Сreate actions for class B")
        return "Result B"

I thought it should be like this (but of course it doesn't work):

class Child(Parent):

@Parent.general_create # or @super().general_create
def create(self):
    print("Сreate actions for class Child")
    return "Result Child"
1 Answers

Not sure how you want to use this code... Nonetheless if you want to call general_create from the Parent class and not an instance of it (e.g. calling @Parent.general_create) then it needs to be a static method (class method would work but you are not using the class):

class Parent:
    @staticmethod
    def general_create(create_child_func):
        def wrapper(*args, **kwargs):
            print("Some general actions before")
            result = create_child_func(*args, **kwargs)
            print("Some general actions after")
            return result

        return wrapper


class Child(Parent):
    @Parent.general_create
    def create(self):
        print("Сreate actions for class Child")
        return "Result Child"


Child().create()

Whith this usage though there is no need for Child to inherit from Parent and this would work the same:

class Parent:
    @staticmethod
    def general_create(create_child_func):
        def wrapper(*args, **kwargs):
            print("Some general actions before")
            result = create_child_func(*args, **kwargs)
            print("Some general actions after")
            return result

        return wrapper


class Child:
    @Parent.general_create
    def create(self):
        print("Сreate actions for class Child")
        return "Result Child"


Child().create()

Infact there is also no need for a Parent class at all... You could just keep the general_create as a global function:

def general_create(create_child_func):
    def wrapper(*args, **kwargs):
        print("Some general actions before")
        result = create_child_func(*args, **kwargs)
        print("Some general actions after")
        return result

    return wrapper


class Child:
    @general_create
    def create(self):
        print("Сreate actions for class Child")
        return "Result Child"


Child().create()
Related