0

我认为 python 是一种解释性语言,但根据下面的代码片段,它显然没有完全符合我的预期?我对此进行了一些搜索,结果发现如果函数中存在对它的赋值,python 会隐式地将名称“声明”为本地名称。所以它在解释代码时确实做了一些静态分析,但我的问题是多少?例如,如下面的代码所示,由于 x=1 不可达,它是否也会优化?我们是否有更多关于我们如何解释代码的细节?谢谢

x = 10
def f():
    if False: x = 1
    print x
UnboundLocalError: local variable 'x' referenced before assignment
4

2 回答 2

2

在 CPython 中,代码首先被编译成字节码,然后字节码由解释器执行。因此,在执行任何代码之前会发现一些问题(语法错误等)。

如果您愿意,可以使用dis模块检查字节码:

>>> import dis
>>> dis.dis(f)
  3           0 LOAD_GLOBAL              0 (False)
              3 POP_JUMP_IF_FALSE       15
              6 LOAD_CONST               1 (1)
              9 STORE_FAST               0 (x)
             12 JUMP_FORWARD             0 (to 15)

  4     >>   15 LOAD_FAST                0 (x)
             18 PRINT_ITEM          
             19 PRINT_NEWLINE       
             20 LOAD_CONST               0 (None)
             23 RETURN_VALUE        

如您所见,这个特殊的 CPython 在将 Python 转换为字节码时并没有做很多优化。

于 2013-01-03T20:27:43.257 回答
2

这里没有“静态分析”,至少不像通常解释的那样。只有编译。

当你到达一个def块的末尾时,在主体上调用编译器将其转换为一个code对象,这与在 REPL 中输入的行上调用编译器的方式几乎相同。

它并不关心分配发生在if永远不会发生的语句中。它仍然编译该if块内的代码。因此,它正在编译对x. 编译def块的一部分是创建locals字典,当它编译该赋值时,它知道x是局部变量而不是全局变量,这就是它所需要的。

于 2013-01-03T20:29:24.293 回答