python装饰器中变量的范围 - 更改参数

Zaa*_*Hai 5 python decorator

我有以下带参数的装饰器:

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
Run Code Online (Sandbox Code Playgroud)

尝试使用装饰器导致:

>>> @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
>>>
Run Code Online (Sandbox Code Playgroud)

为什么我不能改变p

Bre*_*arn 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,它都不会真正实现任何目标.