準備知識:1.在python直譯器開始執行之後,機會在記憶體中開闢乙個空間,每當遇到
乙個變數的時候,就把變數和值之間的關係記錄下來,但是當遇到函式定義
的時候,直譯器只是把函式名讀入記憶體,表示這個函式存在,至於函式內部
的變數和邏輯,直譯器是不關心的。也就是說一開始的時候函式只是載入進
來,僅此而已,只有當函式被呼叫和訪問的時候直譯器才會根據函式內部聲
明的變數來進行開闢變數的內部空間。隨著函式執行完畢,這些函式內部變
量占用的空間也會隨著函式執行完畢而清空。
例子:def fun():
a = 10000
print(a)
fun()
print(a) # a不存在了了已經..
2.命名空間
在乙個python程式的任何乙個地方,都存在幾個可用的命名空間。
我們存放名字和值的關係的空間起個名字,叫命名空間。
我們的變數在儲存的時候就存在這片空間的。
(1)分類:
1)每個函式都有自己的命名空間,叫做區域性命名空間,
它記錄了函式的變數,包括函式的引數和區域性定義的變數。
2)每個模組都擁有自己的命名空間,叫做全域性命名空間,
它記錄了模組的變數,包括函式、類、其他匯入的模組、
模組級的變數和常量。
3)還有就是內建命名空間,任何模組均可訪問,它存放著
內建的函式和異常。
載入順序:內建命名空間,全域性命名空間,區域性命名空間(函式被執行)
取值順序:區域性命名空間,全域性命名空間,內建命名空間
注意:巢狀函式的情況
1.先在當前(巢狀的或lambda)函式的命名空間搜尋
2.然後是在父函式的命名空間中搜尋
3.接著是模組命名空間中搜尋
4.左後在內建命名空間中搜尋
(2)生命週期:
命名空間的生命週期不同的命名空間在不同的時刻建立,
有不同的生存期。
1、內建命名空間在 python 直譯器啟動時建立,
會一直保留,不被刪除。
2、模組的全域性命名空間在模組定義被讀入時建立,
通常模組命名空間也會一直儲存到直譯器退出。
3、當函式被呼叫時建立乙個區域性命名空間,當函
數返回結果或丟擲異常時,被刪除。每乙個遞迴
呼叫的函式都擁有自己的命名空間。
3.作用域
l :local,區域性作用域,即函式定義的變數
e :enclosing,巢狀的父級函式的區域性作用域,
即包含此函式的上級函式的區域性作用域但不是全域性
g :global, 全域性變數,就是模組級別定義的變數。
b :built-in,系統固定模組裡面的變數。比如int等。
搜尋變數的優先順序順序:legb
1.globals() 和 locals()
globals() 獲取到全域性作用域(內建,全域性)中的所有名字
locals() 檢視當前作用域中的所有名字
例子:a = 10
def func():
a = 20
print(a) # 就近原則
print(globals()) # globals() 獲取到全域性作用域(內建,全域性)中的所有名字
print(locals()) # locals() 檢視當前作用域中的所有名字
func()
列印內容:
(1)#20
(2)#, '__builtins__': ,
#'__file__': '/users/busensei/wzy/test.py', '__cached__': none, 'a': 10,
#'func': }
(3)#
2. global 和 nonlocal
global:尋找全域性作用域中的內容(宣告在區域性作用域裡使用全域性作用域的變數)
nolocal :宣告在區域性作用域裡,使用上層區域性作用域的變數, 且上層不可以是全域性變數
通過例子來加深理解:
<1>
a = 10
def func():
global a # a 不再是區域性變數. 是全域性變數
a = 30 # 把全域性中的a重新賦值成30
print(a) #30
func()
print(a) #30
<2>
a = 10
def func1():
a = 40
def func2():
nonlocal a # 找區域性作用域中 離他最近的那個變數引入進來
a = 20
print(a)#20 這時被引入的變數a的值從40變成了20
func2()
print(a)#20 這時這層的a已經被20所覆蓋
func1()
print(a)#10 nonlocal是在他外層找到值停止,如果沒有到全域性就回報錯,不會到全域性
結果:20
2010
<3>
a = 10
def fun1():
a = 20
def fun3():
def fun2():
nonlocal a
a = a + a
print(a)#40
fun2()
fun3()
print(a)#40
fun1()
print(a)#10
結果:40
4010
<4>
a = 10
def fun1():
def fun3():
b = 30
def fun2():
global a
nonlocal b
a = a + b
print(a)#40
fun2()
fun3()
print(a)#40
fun1()
print(a)#40
結果:40
4040
《練習》
a = 1
def fun_1():
a = 2
def fun_2():
nonlocal a
a = 3
def fun_3():
a = 4
print(a)
print(a)
fun_3()
print(a)
print(a)
fun_2()
print(a)
print(a)
fun_1()
print(a)
結果:123
43
31
Python命名空間和作用域
乙個命名空間中不能有重名,但不同的命名空間是可以重名而沒有任何影響。命名空間的生命週期取決於物件的作用域,如果物件執行完成,則該命名空間的生命週期就結束。因此,我們無法從外部命名空間訪問內部命名空間的物件。內建作用域是通過乙個名為 builtin 的標準模組來實現的,預定義了哪些變數 python ...
python命名空間和作用域
namespace 命名空間 命名空間 內建 命名空間 python直譯器啟動之後就可以使用的變數 函式名 全域性 命名空間 在函式外面的變數名 函式名 區域性 命名空間 每乙個函式都擁有自己的命名空間 python直譯器執行 載入順序 所有 內建空間函式名 變數 逐行 載入全域性空間變數 函式名 ...
Python命名空間和作用域
一 命名空間namespacs 存放名字的地方,是對棧區的劃分 有了命名空間之後,就可以在棧區中存放相同的名字,詳細的,命名空間 分為三種 1.1 內建命名空間 存放的名字 存放的python直譯器內建的名字 print input 存活週期 python直譯器啟動則產生,python直譯器關閉則銷...