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
?
@Reboot_87: you can't; the objects you're passing in are immutable and it's therefore impossible to change them, and you can't re-bind the names in the outer scope just based on what's passed in.
Some values in python can be modified, and some cannot. This does not ever mean that we can't change the value of a variable – but if a variable contains a value of an immutable type, we can only assign it a new value. We cannot alter the existing value in any way.
The decorator arguments are accessible to the inner decorator through a closure, exactly like how the wrapped() inner function can access f . And since closures extend to all the levels of inner functions, arg is also accessible from within wrapped() if necessary.
Dynamic Function Arguments We simply can make solve_for() accept *args and **kwargs then pass that to func() . Of course, you will need to handle the arguments in the function that will be called.
Because you assign to p
inside wrapper
, Python treats the p
inside wrapper
as local to wrapper
. In Python 3 you can use nonlocal p
to mark p
as 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. p
is already only local to pdecor
. No code outside pdecor
can access p
, so decrementing it won't have any effect on any code elsewhere. So whether you can decrement p
or not, it won't really accomplish anything.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With