I am working on a decorator. To avoid duplicating code I am inheriting a parent decorator which has a nonlocal variable defined. I am not able to get the exact behaviour in my child decorator as I am not able to modify this variable in the parent decorator.
def parentDecorator(func):
initial=False
def wrapped(*args,**kwargs):
nonlocal initial
if initial:
print("gettting executed after initial call")
return func(*args,**kwargs)
else:
print("getting executed before initial call")
initial=True
res=func(*args,**kwargs)
return res
return wrapped
def evaluateCondition():
return True
def childDecorator(func):
def wrapped(*args,**kwargs):
if evaluateCondition():
myFunc=parentDecorator(func)
return myFunc(*args,**kwargs)
else:
print("do nothing")
return wrapped
class decoratorTestClass():
def __init__(self):
print('init called')
@childDecorator
def execute(self):
print("Hello from execute function")
dc=decoratorTestClass()
dc.execute() # this should be called before initialized
dc.execute() # this should be called after initialized
In both the cases the function is getting printed in the else call in the parent decorator. How can I achieve this? I can't change anything in the parent decorator.
The problem with your child decorator is that it is applying your parent decorator multiple times to your method instead of applying it a single time (i.e. you're creating a different closure on each execution of your decorated function). Moving the call to parentDecorator
to before the definition of wrapped
should fix the issue you're facing:
def childDecorator(func):
myFunc = parentDecorator(func) # Move this here
def wrapped(*args,**kwargs):
if evaluateCondition():
return myFunc(*args,**kwargs)
else:
print("do nothing")
return wrapped