Python 之作用域和名字空間

2022-09-16 01:51:15 字數 2563 閱讀 6779

python有乙個核心概念是名字空間(namespace),namespace是乙個name到object 的對映關係,python有很多namespace,因此,在**中如果碰到乙個標誌符(name),需要有乙個規則來決定去哪個namespace查詢——這就是legb。

legb決定了name的查詢順序:locals -> enclosing function -> globals -> __builtins__

所以,在 python 中檢索乙個變數的時候,優先到 locals 裡面來檢索,檢索不到的情況下會檢索 enclosing ,enclosing 沒有則到 globals 全域性變數裡面檢索,最後是到 builtins 裡面來檢索。

當然,因為 builtins 的特殊性,我們可以直接在 builtins 裡面新增變數,這樣就可以在任意模組中訪問變數,不過這種方法太過於**,不推薦這麼做。

lgb規則(閉包是一種特殊的作用域,暫不考慮)與name space載入的順序相反,python直譯器初始化的時候會先載入built-in namespace,它由__builtins__模組的名字構成,隨後載入global namespace。 如果在執行期間呼叫了乙個函式,那麼將建立區域性名字空間。

python中一切都是object,包括function、module、class、package,這些objects都有在記憶體中真真正正的存在。每個object都有自己的namespace,每個object的namespace是獨立的,可以通過object.name的方式訪問object的namespace中的name,因此,不同的namespace中可以使用相同的name,而不會引發混淆。namespace是動態建立的,每乙個namespace的生存時間也不一樣。例如,乙個module的namespace是它被import的時候建立的。而function被呼叫時,建立其local namespace,呼叫結束或丟擲exception的時候, 該local namespace將被刪除。

locals( )和globals( )分別返回dictionary結構的global namespace和local namespace,例如:

a = 3

defproc():

a = 3

print

(locals())

print

(globals())

proc()

可以看見,區域性作用域和全域性作用域都有變數a,但它們不是同乙個物件。

注意:還有乙個特殊的module,一進入python直譯器,就建立了乙個module,這個module的namespace就是global namespace,乙個全域性唯一的namespace。這個module的乙個內部的attribute,__name__等於__main__。如果模組是被匯入的,__name__的值為模組的名字;如果模組是被直接執行的,__name__的值為』__main__』。

scope(作用域):用unqualified reference name(即與object.name相比,沒有object的字首)就可以直接找到name所指的物件。 lgb規則用scope的概念來解釋就是:在任何**執行的時候,都至少有3個scope,從內到外一次查詢乙個unqualified reference name。

函式體內的區域性變數和全域性變數如果重名,全域性變數不可見(被區域性變數覆蓋)。

x = 50

deffunc(x):

print('

x=', x) #

50 x = 2

print('

x=', x) #

2func(x)

print('

x=', x) #

50

乙個更複雜的例子:

j, k = 1, 2

defproc1():

j, k = 3, 4

print

"j==%d and k=%d

" %(j,k)

k = 5

defproc2():

j = 6proc1()

print

"j==%d and k=%d

" %(j,k)

k = 7proc1()

print

"j==%d and k=%d

" %(j,k)

j = 8proc2()

print

"j==%d and k=%d

" %(j,k)

當在函式中需要修改全域性變數時,如果沒有global關鍵字則會出錯:

x = 50

defrun():

print

x x = 2run()

報錯為:unboundlocalerror: local variable 'x' referenced before assignment

加上global關鍵字以後則ok

x = 50

defrun():

global

x x = 2run()

print x #

2

python之作用域

跟很多程式語言一樣,python中也有作用域的使用 函式和變數分有公開的以及非公開的 正常的函式和變數名是公開的 public 比如abc,x123,pi 類似 這樣的變數是特殊變數,可以被直接引用,但是有特殊用途,我們自己的變數一般不用這種變數名 類似 和 的函式和變數就是非公開的private,...

js之作用域

1.什麼是作用域 作用域是用於收集儲存維護變數,以及當前執行 宣告的變數所擁有的許可權,例如 function foo a foo1 666 function foo2 a g a 在foo2函式中 a向g賦值 此時g在foo2作用域中也不存在,他也向上查詢,遇到window物件,發現其中也沒有定義...

Python命名空間和作用域

乙個命名空間中不能有重名,但不同的命名空間是可以重名而沒有任何影響。命名空間的生命週期取決於物件的作用域,如果物件執行完成,則該命名空間的生命週期就結束。因此,我們無法從外部命名空間訪問內部命名空間的物件。內建作用域是通過乙個名為 builtin 的標準模組來實現的,預定義了哪些變數 python ...