python装饰器中变量的范围-更改参数
问题内容:
我有以下带有参数的装饰器:
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
尝试使用装饰器会导致:
>>> @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
>>>
为什么我不能更改p
?
问题答案:
由于您将p
内部分配给wrapper
Python,因此Python将p
内部wrapper
视为wrapper
。在Python
3中,您可以使用nonlocal p
标记p
为从外部作用域引用。在Python 2中,虽然可以通过将相同的值作为关键字参数(例如def decorator(fn, p=p)
)传递到嵌套函数中来获得对相同值的引用,但无法分配给中间p 。
但是,目前还不清楚您在做什么。
p
已经只在本地pdecor
。外部没有代码pdecor
可以访问p
,因此递减不会对其他任何代码产生任何影响。因此,无论您是否可以递减p
,它都不会真正完成任何事情。