[英]Decorator running error: "UnboundLocalError: local variable 'count' referenced before assignment"
I created two variables inside two different decorators, and one decorator works good but the other one shows an error.我在两个不同的装饰器中创建了两个变量,一个装饰器运行良好,但另一个显示错误。
def running_average(func):
data = {'total': 0, 'count': 0}
def wrapper(*args, **kwargs):
print(data)
val = func(*args, **kwargs)
data['total'] += val
data['count'] += 1
print('Average of {} so far: {:.01f}'.format(func.__name__,
data['total']/data['count']))
return func(*args, **kwargs)
return wrapper
@running_average
def foo(x):
return x + 2
This foo function works.这个 foo 函数有效。
def countcalls(func):
count = 0
print(count)
def wrapper(*args, **kwargs):
print(count)
count += 1
print('# of calls: {}'.format(count))
return func(*args, **kwargs)
return wrapper
@countcalls
def boo(x):
return x + 2
But this boo
function shows error: UnboundLocalError: local variable 'count' referenced before assignment
.但是这个
boo
函数显示错误: UnboundLocalError: local variable 'count' referenced before assignment
。
From my understanding, these two functions follow the same pattern.根据我的理解,这两个函数遵循相同的模式。 In both decorators, a variable is defined in the decorator, and the variable is used in the wrapper function.
在两个装饰器中,都在装饰器中定义了一个变量,在包装函数中使用了该变量。 However, this
foo
function works good, but this boo
function doesn't work.但是,这个
foo
函数很好用,但是这个boo
函数不起作用。 I was wondering what is the reason?我想知道是什么原因?
The difference is that in the first example, the name data
always refers to the same object;不同的是,在第一个例子中,名称
data
总是指向同一个对象; it is never reassigned.它永远不会被重新分配。 The dictionary
data
refers to is itself mutated (changed), but it is always the same object.字典
data
所指的本身是变异(改变)的,但它始终是同一个对象。
In contrast, when you do count += 1
in your second example, that changes the value that the name count
refers to.相反,当您在第二个示例中执行
count += 1
时,会更改名称count
所指的值。 That makes count
a local variable.这使得
count
成为局部变量。 When the interpreter sees this, it notices that you reference the local variable count
before assigning to it, and fails.当解释器看到这一点时,它注意到您在分配给它之前引用了局部变量
count
,并失败了。
The solution is to tell the interpreter to use the count
from the enclosing scope by declaring it nonlocal
解决方案是通过将其声明
nonlocal
来告诉解释器使用来自封闭范围的count
def countcalls(func):
count = 0
print(count)
def wrapper(*args, **kwargs):
nonlocal
print(count)
count += 1
print('# of calls: {}'.format(count))
return func(*args, **kwargs)
return wrapper
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.