I have the following decorator with parameters:
from functools import wraps
def pdecor(p):
def decorator(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
p -= 1
return fn(*args, **wargs)
return wrapper
return decorator
Trying to use the decorator results in :
>>> @pdecor(1)
... def run(): pass
...
>>> run()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in wrapper
UnboundLocalError: local variable 'p' referenced before assignment
>>>
Why can’t I change the p?
Because you assign to
pinsidewrapper, Python treats thepinsidewrapperas local towrapper. In Python 3 you can usenonlocal pto markpas referenced from an outer scope. In Python 2 there is no way to assign to the intermediate p, although you can get a reference to the same value by passing it into the nested functions as a keyword argument (e.g.,def decorator(fn, p=p)).However, it’s not clear what you’re getting at with this anyway.
pis already only local topdecor. No code outsidepdecorcan accessp, so decrementing it won’t have any effect on any code elsewhere. So whether you can decrementpor not, it won’t really accomplish anything.