Python 装饰程序运行错误:";UnboundLocalError:局部变量';计数';作业前参考“;
我在两个不同的装饰器中创建了两个变量,其中一个装饰器工作正常,但另一个显示错误Python 装饰程序运行错误:";UnboundLocalError:局部变量';计数';作业前参考“;,python,decorator,Python,Decorator,我在两个不同的装饰器中创建了两个变量,其中一个装饰器工作正常,但另一个显示错误 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
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
这个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
但此boo
函数显示错误:UnboundLocalError:赋值前引用的局部变量“count”
据我所知,这两种功能遵循相同的模式。在这两个decorator中,都在decorator中定义了一个变量,并在包装器函数中使用该变量。但是,这个
foo
函数工作得很好,但是这个boo
函数不工作。我想知道原因是什么?区别在于,在第一个示例中,名称data
总是指同一个对象;它永远不会被重新分配。所引用的字典数据
本身发生了变异(更改),但它始终是同一个对象
相反,在第二个示例中执行count+=1
时,会更改名称count
引用的值。这使得count
成为一个局部变量。当解释器看到这一点时,它会注意到您在分配给它之前引用了局部变量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