Python 3:变量在范围内重新定义时变得无法解析
Python 3: Variable becomes unresolved when redefined in scope
我正在编写一个装饰器,如果我尝试在任何地方重新定义它们中的任何一个,内部函数会出现一些具有可变范围的奇怪行为。
def decorate_me(a_variable: bool):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(a_variable)
new_variable = not a_variable
new_variable = not new_variable
print(new_variable)
return func(*args, **kwargs)
return wrapper
return decorator
按预期工作,没有问题。但是,如果在最后重新定义 a_variable:
def decorate_me(self, a_variable: bool):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(a_variable)
new_variable = not a_variable
new_variable = not new_variable
print(new_variable)
# --- --- --- --- --- ---
# THIS LINE RIGHT HERE
# --- --- --- --- --- ---
a_variable = not a_variable
return func(*args, **kwargs)
return wrapper
return decorator
这引发了一个错误:
File "...", line 41, in wrapper
print(a_variable)
UnboundLocalError: local variable 'a_variable' referenced before assignment
重新定义变量如何导致它在重新定义之上几行的语句上解除绑定?这里的规则是什么?如何避免?
这在 Python FAQ, and explained here by Eli Bendersky 中得到了回答。这是当你 google 'Python UnboundLocalError'.
时出现的第一件事
来自 Python 的常见问题解答:
This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope. Since the last statement in foo assigns a new value to x, the compiler recognizes it as a local variable. Consequently when the earlier print(x) attempts to print the uninitialized local variable and an error results.
简单地说,重新定义变量就是重新定义它的作用域,从而从外部作用域中移除变量。
解决这个问题的方法是使用 global
或 nonlocal
关键字。在所讨论的示例中,global
将不起作用(因为 a_variable
)不是全局的,但 nonlocal
将起作用。明确地,它告诉内部函数使用外部作用域中的变量。
Eli Bendersky 的解释更深入地解释了为什么会发生这种情况,值得一读。
我正在编写一个装饰器,如果我尝试在任何地方重新定义它们中的任何一个,内部函数会出现一些具有可变范围的奇怪行为。
def decorate_me(a_variable: bool):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(a_variable)
new_variable = not a_variable
new_variable = not new_variable
print(new_variable)
return func(*args, **kwargs)
return wrapper
return decorator
按预期工作,没有问题。但是,如果在最后重新定义 a_variable:
def decorate_me(self, a_variable: bool):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(a_variable)
new_variable = not a_variable
new_variable = not new_variable
print(new_variable)
# --- --- --- --- --- ---
# THIS LINE RIGHT HERE
# --- --- --- --- --- ---
a_variable = not a_variable
return func(*args, **kwargs)
return wrapper
return decorator
这引发了一个错误:
File "...", line 41, in wrapper
print(a_variable)
UnboundLocalError: local variable 'a_variable' referenced before assignment
重新定义变量如何导致它在重新定义之上几行的语句上解除绑定?这里的规则是什么?如何避免?
这在 Python FAQ, and explained here by Eli Bendersky 中得到了回答。这是当你 google 'Python UnboundLocalError'.
时出现的第一件事来自 Python 的常见问题解答:
This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope. Since the last statement in foo assigns a new value to x, the compiler recognizes it as a local variable. Consequently when the earlier print(x) attempts to print the uninitialized local variable and an error results.
简单地说,重新定义变量就是重新定义它的作用域,从而从外部作用域中移除变量。
解决这个问题的方法是使用 global
或 nonlocal
关键字。在所讨论的示例中,global
将不起作用(因为 a_variable
)不是全局的,但 nonlocal
将起作用。明确地,它告诉内部函数使用外部作用域中的变量。
Eli Bendersky 的解释更深入地解释了为什么会发生这种情况,值得一读。