Reputation: 73
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
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
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