2017-09-21 34 views
2

我不明白這個例子中的錯誤。打印6,由Python的LEGB規則?當解釋器在第2行掃描f(a)函數時,是否記住b = 33並放入內存堆或只記得b是局部變量的信息?Python變量作用域和UnboundLocalError

b = 6 
def f(a): 
    print(a) 
    print(b) 
    b = 33 
f(20) 
# UnboundLocalError: local variable 'b' referenced before assignment 

回答

1

當Python掃描你的函數時,它看到一個賦值爲b。此分配會創建指定Python將名稱b作爲局部變量加載的特定字節碼(LOAD FAST)。

你可以看到這一點,如果你拆開字節碼(使用dis模塊)的功能f創建:

from dis import dis 
dis(f) 
    2   0 LOAD_GLOBAL    0 (print) 
       2 LOAD_FAST    0 (a) 
       4 CALL_FUNCTION   1 
       6 POP_TOP 

    3   8 LOAD_GLOBAL    0 (print) 
      10 LOAD_FAST    1 (b) 
      12 CALL_FUNCTION   1 
      14 POP_TOP 

此相關的指令是:

LOAD_FAST    1 (b) 

它加載名稱b作爲局部變量。

當遇到print(b),它會嘗試加載名稱bb尚未確定(轉讓尚未執行):你引用它(print(b))已進行的分配給它。

+0

dis模塊顯示發生了什麼。它是通過讀取函數的全部函數來工作的,然後在屏幕上打印字節碼,還是在每行掃描後打印? –

+0

所有'dis'需要創建你所看到的位於'f .__ code__'中,它不會讀取任何內容,它使用已存在的內容@MarkoSavic –