我有以下带参数的装饰器:
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
?
答案 0 :(得分:8)
由于您在p
内分配给wrapper
,因此Python会将p
内的wrapper
视为wrapper
的本地内容。在Python 3中,您可以使用nonlocal p
将p
标记为从外部作用域引用。在Python 2中,没有办法分配给中间p,尽管你可以通过将它作为关键字参数传递给嵌套函数来获得对相同值的引用(例如,def decorator(fn, p=p)
)。
然而,目前还不清楚你对此有何看法。 p
已经只在pdecor
的本地。 pdecor
之外的代码无法访问p
,因此减少它不会对其他地方的任何代码产生任何影响。因此,无论你是否可以减少p
,它都不会真正实现任何目标。