Rolfsky
Rolfsky

Reputation: 73

Decorator that executes the method it decorates/Get the decorated method name for a specific decorator without executing the decorated method Python

Given:

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        #Some code that will execute the decorated method
        func()
    return wrapper


class parent:

    def parentMethod(self):
        pass

class child(parent):

    @my_decorator
    def childMethod(self):
        print("Child method called")


if __name__ == '__main__':
    childInstance = child()

IS there a way to execute the decorated method without calling the decorated method? If that dosen't make any sense, i want basically every method that is decorated with @my_decorator in child class to be executed when a instance of child class is created.

If both above questions are invalid, is there a way to get the methods that are decorated with "@my_decorator" (the names of the methods) without having to call the decorated methods. As a parallel example, the same way you can get the class name that inherits the parent class with self.__class__.__name__

Upvotes: 0

Views: 46

Answers (2)

Serge Ballesta
Serge Ballesta

Reputation: 149075

It can be done rather easily with the inspect module, by having the decorator add a custom attribute to the method, and using that in __init__:

import inspect

def my_decorator(func):
    print("Something is happening without the function being called.")
    func.deco = True
    return func


class parent:

    def parentMethod(self):
        pass

class child(parent):
    def __init__(self):
        for name, m in inspect.getmembers(self.__class__, inspect.isfunction):
            if hasattr(m, 'deco'):
                m(self)

    @my_decorator
    def childMethod(self):
        print("Child method called")


if __name__ == '__main__':
    childInstance = child()

It gives:

Something is happening without the function being called.
Child method called

The first message is displayed when the child class is defined, the second one when childInstance is initialized.

Upvotes: 1

D Hudson
D Hudson

Reputation: 1092

You can definitely execute every decorated method on instantiation with some clever meta-programming and reflection. However, this will be complex, difficult to debug, and quite painful to deal with when you (or your colleagues) come back to the code.

You're far better off just calling the methods explicitly in the __init__.


If you really want to go down the route of introspecting the class, try these references:

Upvotes: 1

Related Questions