5

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

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

4

1 回答 1

9

因为您分配到pinside wrapper,Python 将pinsidewrapper视为本地到wrapper。在 Python 3 中,您可以使用nonlocal p标记p为从外部范围引用。在 Python 2 中,没有办法分配给中间 p,尽管您可以通过将它作为关键字参数(例如,def decorator(fn, p=p))传递给嵌套函数来获得对相同值的引用。

但是,目前尚不清楚您对此有何看法。 p已经是本地的了pdecor。外部没有代码pdecor可以访问p,因此递减它不会对其他地方的任何代码产生任何影响。因此,无论您是否可以递减p,它都不会真正完成任何事情。

于 2012-08-22T17:27:12.393 回答