命名空間是名稱與對象之間的關系,可以將命名空間看做是字典,其中的鍵是名稱,值是對象。
命名空間不共享名稱。
在命名空間中的名稱能將任何python對象作為值,在不同的命名空間中相同的名稱可以與不同的對象相關聯。但是,如果存在名稱解析協議,則多個命名空間可以一起工作來解析名稱。也就是說,如果有多個命名空間(總是有的),那么可以定義搜索的順序,依次在不同的命名空間里來查找某個名稱(或確認其不存在于任何認可的命名空間)。在python中,將這一過程定義為作用域。
作用域搜索規則:LEGB
L:局部的(local)
E:封閉的(Enclosing)
G:全局的(Global)
B:內置的(Built-in)
一、局部命名空間
函數內部的命名空間,在調用函數的時候生成,調用結束時消失。當局部命名空間有效時,它是第一個用于檢查某個名字存在性的命名空間。如果在局部命名空間內找到該名稱,則返回與名字相關聯的對象,反之提示出錯。
二、全局命名空間
python在模塊中維護命名空間,模塊是一些python文件--包含函數等對象,并且可以導入其他程序使用。當某個模塊被導入之后,該模塊同時引入了一個命名空間,其中包含模塊中所有的名稱和關聯的對象,可以通過存儲在沒個模塊中的__dict__來查看這個命名空間,換句話說,字典就是這個模塊的命名空間。
如果想要引用給模塊中的對象,要使用點符號將名稱和模塊名稱關聯,這實際上是要求將對象與該模塊中的名稱相關聯。
當python啟動解釋器時,它將自動導入兩個模塊,即模塊__main__和__built-ins__。__main__模塊是默認的全局模塊,所有新對象都存儲在其中。可以通過函數globals來訪問該命名空間的字典。子啊平python解釋器中通過輸入用戶交互時,globals是有效的命名空間。
1.局部賦值規則
python中有一種稱為“本地賦值”的規則非常有趣。如果在函數內的任何地方進行局部賦值,則該賦值只在當前活動的命名空間中創建名稱。有時這將產生副作用,舉例如下:
>>>value=27
>>>deffunc(param1,param2):
forkey,valinlocals().items():
print(key,val)
value=value+1
>>>func(98765,43210)
param198765
param243210
Traceback(mostrecentcalllast):
File"",line1,in
func(98765,43210)
File"",line4,infunc
value=value+1
UnboundLocalError:localvariable'value'referencedbeforeassignment
>>>
首先通過賦值在全局命名空間中創建了變量value。也許你會認為,當函數值加1是會先在局部的命名空間中查找變量,無法找到時在全局命名空間中找到該名字。可以并不是這樣。
python提出如下假設,如果在函數體內的任何地方對變量賦值,則python將名稱添加到局部命名空間中。語句value=value+1對對象value進行賦值。python假設無論在何處發生賦值,value都是函數func局部命名空間的一部分。當python嘗試把1跟value相加時,該value名稱在局部命名空間中,但它沒有關聯值,所以python報錯。
問題在于python何時決定使value出現在局部命名空間中。實際value出現在局部命名空間中發生在代碼運行前,即,在python運行到函數定義之前。由于創建命名空間時,python會檢查代碼并填充局部命名空間。在python運行那行代碼之前,就發現了對value的賦值,并把它添加到局部命名空間中,當函數執行時,python解釋器認為value在局部命名空間中但沒有值,所以會產生錯誤。
2.global語句
有一個方法可以解決上面的問題。如果在函數體內,使用global語句將變量聲明為全局變量,那么python不會為該變量在命名空間中創建局部名稱。
三、內置模塊
遵循LEGB搜索規則,如果python不能在局部命名空間中找到某個名稱,則會在全局命名空間中繼續尋找,它尋找到的將是python的內置名稱。
built-in模塊和其他模塊一樣,都具有__dict__屬性,這就是模塊的命名空間
四、封閉式變量
“封閉式”的作用域規則適應于函數定義函數時,也就是說,在函數體內定義了一個新的函數。這個函數體內的函數是外函數的局部命名空間中的一部分,意味著只有在外函數執行期間才能夠運行。完整的LEGB規則是先檢查局部命名空間,之后是封閉在局部命名空間中的其他函數,之后是全局命名空間,在最后以內置命名空間結束。
以上內容為大家介紹了python命名空間與作用域,希望對大家有所幫助,如果想要了解更多Python相關知識,請關注IT培訓機構:千鋒教育。http://www.kei0345678.cn/