I looked at this page to try building a decorator that can be used with OR without arguments (i.e. callable with either @deco
or @deco(arg1='x',arg2='y')
). But I have trouble using the arguments: if I uncomment the 2 commented lines below, I get an UnboundLocalError: local variable 'arg1' referenced before assignment
, but logically this error should also happen when the lines are commented since the variable is not assigned any value in between.
def deco(_func=None, *, arg1=False, arg2='default'):
def outer_wrap(func):
def inner_wrap(*args, **kwargs):
# if not arg1:
# arg1 = 'blah'
return 'arg1: '+str(arg1)+', arg2: '+str(arg2)
return inner_wrap
if _func is None: # case when @deco is called with arguments
return outer_wrap
else: # case without arguments
return outer_wrap(_func)
@deco
def I(n):
return n
I(1)
There must be something I'm missing here, any help to understand why this happens would be welcome. (I used Python 3.8.3)
EDIT Thanks to the following answers I modified my code by adding arg1 and arg2 as arguments of the wrapper functions as well:
def deco(_func=None, *, arg1=False, arg2='default'):
def outer_wrap(func, arg1=arg1, arg2=arg2):
def inner_wrap( *args, arg1=arg1, arg2=arg2, **kwargs):
if not arg1:
arg1 = 'blah'
return 'arg1: '+str(arg1)+', arg2: '+str(arg2)
return inner_wrap
if _func is None:
return outer_wrap
else:
return outer_wrap(_func)
@deco #can add or remove arguments here
def I(n):
return n
print(I(5))