V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
scriptB0y
V2EX  ›  问与答

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

  •  
  •   scriptB0y · 2017-08-08 17:31:26 +08:00 · 1753 次点击
    这是一个创建于 2649 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我不明白的地方是,到 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
    
    4 条回复    2017-08-08 18:34:15 +08:00
    chenstack
        1
    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
        2
    scriptB0y  
    OP
       2017-08-08 18:20:57 +08:00
    @chenstack 先生成函数对象(这算是预编译吗?),再编译成字节码吗?
    chenstack
        3
    chenstack  
       2017-08-08 18:30:30 +08:00
    想深入了解的话可以读一下 python 的源码,其实生成函数对象时已经生成字节码了。__code__里也有很多学问的,另外也有一些内建函数可以手动编译出 code object。
    scriptB0y
        4
    scriptB0y  
    OP
       2017-08-08 18:34:15 +08:00
    @chenstack 嗯,但是我这里想急着弄明白,当分析到 print 这一行的时候,并没有分析到下一行,这个时候怎么决定 x 是 local 还是 global 呢?(我知道如果是 local 的话,这一行要编译出 LOAD_FAST,否则是 LOAD_GLOBAL )

    是否是先全部分析一遍这个函数的所有赋值,然后回来生成字节码?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1118 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:52 · PVG 02:52 · LAX 10:52 · JFK 13:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.