tem*_*ame 4 python scope compilation python-3.x
x = 4
def test():
print(x)
x = 2
test()
Run Code Online (Sandbox Code Playgroud)
这会产生错误,因为当你去的时候print(x),它会看到你x在函数的范围内声明了test它,并且它告诉你你在没有声明的情况下尝试引用它.
我知道,如果我这样做global x没有问题,或者如果我移动打印声明......我知道.
但是我不明白解释器是如何知道我x在print语句之后重新声明的,如果它一次通过代码一行.怎么知道会发生什么?
显然,这比我所知道的要多得多.
谁告诉你Python一次执行一行?Python一次执行一个字节码.该字节码来自编译器,它一次只能运行一个语句.语句可以是多行.函数定义是一个声明.
因此,编译函数定义的第一步是收集在该函数体内分配的所有变量.已分配但没有global或nonlocal声明的任何变量都是本地变量.
(作为旁注,该函数体实际上并没有被编译成函数,它被编译成一个code对象,它被隐藏在某个地方,只在你调用函数时运行,并进入一些字节码,function从该code对象构建一个对象,以正常顺序发生函数定义时运行.)
实际上,您可以通过查看其成员来查看编译器对您的函数所做的操作:
>>> def foo():
... global y
... x=1
... y=1
>>> foo.__code__.co_varnames
('x',)
Run Code Online (Sandbox Code Playgroud)
然后,当它为您的函数体创建字节码时,所有变量co_varnames都被编译为本地查找,而其余变量则被编译为全局查找:
>>> dis.dis(foo)
3 0 LOAD_CONST 1 (1)
3 STORE_FAST 0 (x)
4 6 LOAD_CONST 1 (1)
9 STORE_GLOBAL 0 (y)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
138 次 |
| 最近记录: |