如何在函数中检测变量赋值?
How are variable assignments detected in a function?
尝试执行以下代码时:
a = 1
def test_variable():
if False:
a = 2
print(a)
test_variable()
失败 UnboundLocalError: local variable 'a' referenced before assignment
。
这与 Python 中局部变量和全局变量的工作方式一致(source,重点是我的):
variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.
然而,当反汇编函数的代码时,我得到:
5 0 LOAD_GLOBAL 0 (print)
2 LOAD_FAST 0 (a)
4 CALL_FUNCTION 1
6 POP_TOP
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
我们看到变量 a
上没有 STORE_FAST
指令的痕迹。
因此,我想知道如果字节码中不存在变量赋值,解释器如何知道它?或者,从相反的角度来表述:如果解释器足够聪明,可以完全跳过 if False
块,为什么代码不执行?
赋值是由解析器检测到的,而不是由字节码解释器检测到的。因为它在函数的某处看到了赋值,所以它将 a
视为局部变量。 LOAD_FAST
指令访问局部变量,由于变量不存在而报错
添加global a
语句并比较反汇编结果。我觉得LOAD_FAST
会改成LOAD_GLOBAL
.
尝试执行以下代码时:
a = 1
def test_variable():
if False:
a = 2
print(a)
test_variable()
失败 UnboundLocalError: local variable 'a' referenced before assignment
。
这与 Python 中局部变量和全局变量的工作方式一致(source,重点是我的):
variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.
然而,当反汇编函数的代码时,我得到:
5 0 LOAD_GLOBAL 0 (print)
2 LOAD_FAST 0 (a)
4 CALL_FUNCTION 1
6 POP_TOP
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
我们看到变量 a
上没有 STORE_FAST
指令的痕迹。
因此,我想知道如果字节码中不存在变量赋值,解释器如何知道它?或者,从相反的角度来表述:如果解释器足够聪明,可以完全跳过 if False
块,为什么代码不执行?
赋值是由解析器检测到的,而不是由字节码解释器检测到的。因为它在函数的某处看到了赋值,所以它将 a
视为局部变量。 LOAD_FAST
指令访问局部变量,由于变量不存在而报错
添加global a
语句并比较反汇编结果。我觉得LOAD_FAST
会改成LOAD_GLOBAL
.