Python 编译时什么时候建符号表?

2017-08-08 17:31:26 +08:00
 scriptB0y

我不明白的地方是,到 print 这一行如何知道 x 是 local 还是 global 呢?到这一步还没有分析赋值语句,怎么会当做 local 来对待?

难道是先分析一遍建立符号表,然后再分析一遍进行语法分析?

In [1]: x = 10

In [2]: def func():
   ...:     print(x)
   ...:     x = 20
   ...:

In [3]: func()
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-3-08a2da4138f6> in <module>()
----> 1 func()

<ipython-input-2-84a4e5530b9a> in func()
      1 def func():
----> 2     print(x)
      3     x = 20
      4

UnboundLocalError: local variable 'x' referenced before assignment
1671 次点击
所在节点    问与答
4 条回复
chenstack
2017-08-08 18:19:14 +08:00
因为是在函数中,函数对象构造时会生成 local 变量名表。
比如上述 func,当函数中有 x = 20 时,
func.__code__.co_varnames 是 ('x',)
当只有 print(x)时
func.__code__.co_varnames 是 ()
def 关键字其实就是生成函数对象的
scriptB0y
2017-08-08 18:20:57 +08:00
@chenstack 先生成函数对象(这算是预编译吗?),再编译成字节码吗?
chenstack
2017-08-08 18:30:30 +08:00
想深入了解的话可以读一下 python 的源码,其实生成函数对象时已经生成字节码了。__code__里也有很多学问的,另外也有一些内建函数可以手动编译出 code object。
scriptB0y
2017-08-08 18:34:15 +08:00
@chenstack 嗯,但是我这里想急着弄明白,当分析到 print 这一行的时候,并没有分析到下一行,这个时候怎么决定 x 是 local 还是 global 呢?(我知道如果是 local 的话,这一行要编译出 LOAD_FAST,否则是 LOAD_GLOBAL )

是否是先全部分析一遍这个函数的所有赋值,然后回来生成字节码?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/381427

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX