2016-07-27 101 views
1

当我执行为什么我在第二个代码中得到UnboundLocalError,但不是在第一个代码中?

x = 0 

def f(): 
    print('x' in locals()) 
    x = 1 
    print('x' in locals()) 

f() 

我得到了我希望,即

False 
True 

然而,当我执行

x = 3 

def f(): 
    print(x, 'x' in locals()) 
    x = 7 
    print(x, 'x' in locals()) 

f() 

我希望得到

3 False 
7 True 

但相反,我得到了UnboundLocalError

如果Python知道在下一行有本地作用域中标签x的分配(因此名称x已经在本地作用域中,但它尚未分配),那么为什么它会让我在我的第一个代码中询问x

新增

为什么会引发错误,即使x = 7来自第一print(x, 'x' in locals())后?

+0

只是在FYI这里,但不要在实际代码中使用'locals()'。或'globals()'。或'eval()'。或'exec()'。 – TigerhawkT3

+1

第一次搜索'locals()'中的字符'“x”'。第二个函数试图使用变量'x'然后赋值给它。如果您想使用全局版本,请指定'global x'。见http://stackoverflow.com/questions/370357/python-variable-scope-error – cdarke

+0

@ TigerhawkT3:谢谢。我只是在尝试学习时使用它。 – Leo

回答

0

错误来自打印x,而不是来自'x' in locals()。当你做'x' in locals()时,你实际上没有对变量x做任何事情,因为你给它一个字符串值,而不是对变量的引用。

2

dis.dis用于第一功能:

2   0 LOAD_CONST    1 ('x') 
       3 LOAD_GLOBAL    0 (locals) 
       6 CALL_FUNCTION   0 
       9 COMPARE_OP    6 (in) 
      12 PRINT_ITEM 
      13 PRINT_NEWLINE 

    3   14 LOAD_CONST    2 (1) 
      17 STORE_FAST    0 (x) 

    4   20 LOAD_CONST    1 ('x') 
      23 LOAD_GLOBAL    0 (locals) 
      26 CALL_FUNCTION   0 
      29 COMPARE_OP    6 (in) 
      32 PRINT_ITEM 
      33 PRINT_NEWLINE 
      34 LOAD_CONST    0 (None) 
      37 RETURN_VALUE 

dis.dis为第二功能:

2   0 LOAD_FAST    0 (x) 
       3 LOAD_CONST    1 ('x') 
       6 LOAD_GLOBAL    0 (locals) 
       9 CALL_FUNCTION   0 
      12 COMPARE_OP    6 (in) 
      15 BUILD_TUPLE    2 
      18 PRINT_ITEM 
      19 PRINT_NEWLINE 

    3   20 LOAD_CONST    2 (7) 
      23 STORE_FAST    0 (x) 

    4   26 LOAD_FAST    0 (x) 
      29 LOAD_CONST    1 ('x') 
      32 LOAD_GLOBAL    0 (locals) 
      35 CALL_FUNCTION   0 
      38 COMPARE_OP    6 (in) 
      41 BUILD_TUPLE    2 
      44 PRINT_ITEM 
      45 PRINT_NEWLINE 
      46 LOAD_CONST    0 (None) 
      49 RETURN_VALUE 

临界差是线:4 26 LOAD_FAST 0 (x)

基本上,在当前范围内有一个名为x的赋值语句,因此x被解析为本地名称。解析在编译阶段执行。编译的字节码使用LOAD_FAST而不是LOAD_GLOBAL

编译成字节码和执行是two independent steps - 语言实际上并不是逐行解释的。

相关问题