【问题标题】:Scope of variables in python decorators - changing parameterspython装饰器中的变量范围-更改参数
【发布时间】:2012-08-18 04:21:17
【问题描述】:

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

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

【问题讨论】:

标签: python decorator


【解决方案1】:

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

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

【讨论】:

  • 最初我想编写一个“重试”装饰器,它可以重试运行函数给定的次数。所以我会尝试运行fn 并减少pfn 引发异常,直到我退出p 重试或fn 成功。但是现在我很高兴 Python 没有让我这样做,否则装饰函数的所有执行都将共享相同的重试计数器,对吧?
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 2020-10-09
相关资源
最近更新 更多