初學python名稱空間和LEGB原則
Python的名稱空間是一個字典,字典內儲存了變數名稱與物件之間的對映關係,因此,查詢變數名就是在名稱空間字典中查詢鍵-值對,想要打印出全域性變數與區域性變數的字典對映,我們可以使用函式globals()和locals()。
Python有多個名稱空間,因此需要有規則來規定,LEGB就是用來規定名稱空間查詢順序的規則,順序為:local-->enclosing function locals-->global-->builtin。
LEGB原則如下:
函式中變數命令空間易錯點:
1.python賦值語句特殊 。
下圖這個,會報錯UnboundLocalError: local variable 'b' referenced before assignment,說b未賦值就引用了。
本質原因是python在賦值語句中先看左邊變數是否在區域性名稱空間中有同名的,且無global等關鍵字對其宣告(用到全域性變數必須global,但是不建議這樣使用,全域性變數一般被多個函式用到,如果隨意更改則會導致意想不到的各種錯誤)。如果存在則按LEGB原則處理,否則python會自己在區域性名稱空間新建此區域性變數使用,再計算賦值語句右邊的公式,其餘情況均按LEGB法則。
這個例子是先發現賦值語句左邊變數b在函式a中無同名的變數,也沒有global b,所以新建了一個區域性變數b,然後開始計算b+1,但是此時區域性變數b只宣告並沒有賦值,所以b+1無法計算,導致報錯。
有個辦法解決:1.將賦值語句左邊b改為一個新的變數名 print(新變數) 2.在a()中global下b,表示此b也就是全域性變數b。
2.類變數最好用類名.變數名方式訪問,防止類變數和例項變數混合。-------需要後續理解後補充。
3.python中for迴圈會汙染名稱空間,在C語言中for迴圈中的區域性變數會隨著迴圈語句而結束釋放掉。但python中卻不會,區域性變數會影響迴圈後的程式碼。
C語言中迴圈結束後,此i會不存在,而python中迴圈結束後,還可以訪問到i,而且i是最後迴圈結束時候的值。此段程式碼結果是9.