解讀Python程式設計中的命名空間與作用域

2021-09-24 12:16:18 字數 2265 閱讀 7228

變數是擁有匹配物件的名字(識別符號)。命名空間是乙個包含了變數名稱們(鍵)和它們各自相應的物件們(值)的字典。

乙個python表示式可以訪問區域性命名空間和全域性命名空間裡的變數。如果乙個區域性變數和乙個全域性變數重名,則區域性變數會覆蓋全域性變數。

每個函式都有自己的命名空間。類的方法的作用域規則和通常函式的一樣。

python會智慧型地猜測乙個變數是區域性的還是全域性的,它假設任何在函式內賦值的變數都是區域性的。

因此,如果要給全域性變數在乙個函式裡賦值,必須使用global語句。

global varname的表示式會告訴python, varname是乙個全域性變數,這樣python就不會在區域性命名空間裡尋找這個變數了。

命名空間的定義

python命名空間是名稱到物件的對映,這就像是字典,鍵名是變數名,值是變數的值。比如:    

可以看到變數x,3以字典的形式存放在globals空間內。以之對應的名字空間還有:locals()。  

實際上,你可以通過向名字新增鍵名和值:

上圖左側是內建命名空間,右側是不同的模組,有各自的全域性命名空間,全域性命名空間內定義函式就會有區域性命名空間。

命名空間的種類

python中有三種命名空間:

a) 區域性,函式內的命名空間就是區域性的;

b) 全域性,模組內的命名空間就是全域性的;

c) 內建,包括異常型別、內建函式和特殊方法,可以**中任意地方呼叫;

下面討論關於名字空間的搜尋順序,先來看張圖:

命名空間的可見性(作用域)

a) 內建命名空間在**所有位置都是可見的,所以可以隨時被呼叫;

b) 全域性命名空間和區域性命名空間中, 如果有同名變數,在全域性命名空間處,區域性命名空間內的同名變數是不可見的;

c) 在區域性命名空間處,全域性命名空間的同名變數是不可見的(只有變數不同名的情況下,可使用 global關鍵字讓其可見)。

知道了可見性,下面說變數的查詢順序就要清楚多了。

命名空間的查詢順序

a) 如果在函式內呼叫乙個變數,先在函式內(區域性命名空間)查詢,如果找到則停止查詢。否則在函式外部(全域性命名空間)查詢,如果還是沒找到,則查詢內建命名空間。如果以上三個命名都未找到,則丟擲nameerror 的異常錯誤。

b) 如果在函式外呼叫乙個變數,則在函式外查詢(全域性命名空間,區域性命名空間此時不可見),如果找到則停止查詢,否則到內建命名空間中查詢。如果兩者都找不到,則丟擲異常。只有當區域性命名空間內,使用global 關鍵字宣告了乙個變數時,查詢順序則是 a) 的查詢順序。

為了幫助理解,來舉個例子,我們在全域性命名空間裡定義乙個變數money。我們再在函式內給變數money賦值,然後python會假定money是乙個區域性變數。然而,我們並沒有在訪問前宣告乙個區域性變數money,結果就是會出現乙個unboundlocalerror的錯誤。取消global語句的注釋就能解決這個問題。

在這裡,特殊字串變數__name__指向模組的名字,__file__指向該模組的匯入檔名。

globals()和locals()函式

根據呼叫地方的不同,globals()和locals()函式可被用來返回全域性和區域性命名空間裡的名字。

如果在函式內部呼叫locals(),返回的是所有能在該函式裡訪問的命名。

如果在函式內部呼叫globals(),返回的是所有在該函式裡能訪問的全域性名字。

兩個函式的返回型別都是字典。所以名字們能用keys()函式摘取。

reload()函式

當乙個模組被匯入到乙個指令碼,模組頂層部分的**只會被執行一次。

因此,如果你想重新執行模組裡頂層部分的**,可以用reload()函式。該函式會重新匯入之前匯入過的模組。語法如下:    

reload(module_name) 

在這裡,module_name要直接放模組的名字,而不是乙個字串形式。比如想過載hello模組,如下:    

reload(hello)

解讀Python程式設計中的命名空間與作用域

這篇文章主要介紹了python程式設計中的命名空間與作用域,是python入門學習中的重要知識,需要的朋友可以參考下 變數是擁有匹配物件的名字 識別符號 命名空間是乙個包含了變數名稱們 鍵 和它們各自相應的物件們 值 的字典。乙個python表示式可以訪問區域性命名空間和全域性命名空間裡的變數。如果...

關於flex中mx internal命名空間

flex中好多的變數都是由mx internall命名空間作字首的,代表這個變數在以後的flex builder版本裡可能會有所改變,所以要謹用 下面是具體的應用方法 import mx.controls.tree import mx.core.mx internal use namespace m...

C 中string為空 詳細解讀

c 判斷字串為空 的 方法們 按照效能排序 a.length 0 a string.empty a c 中大多數時候 和string.empty可以相互使用,但是string.empty效能更好,原因 分配乙個長度為0的儲存空間 string.empty 記憶體並沒有為字元分配空間。是否為空的最佳方...