標籤:臨時 函數 space 結果 python函數 瞭解 outer 就是 UNC
python中函數範圍
在python中,一個函數就是一個範圍
name = ‘xiaoyafei‘def change_name(): name = ‘肖亞飛‘ print(‘在change_name裡的name:‘,name)change_name() # 調用函數print("在外面的name:",name)
運行結果如下:
在change_name裡的name: 肖亞飛在外面的name: xiaoyafei
我們再試一下在嵌套函數中是如何的尋找的?
age = 15def func(): print(‘第一層age:‘,age) # 第一層age: 15 def func2(): age = 73 print("func2中的age:",age) # func2中的age: 73 def func3(): age = 84 print("func3中的age:",age) # func3中的age: 84 func3() # 調用func3函數 func2() # 調用func2函數func()
在以上嵌套函數中,就能夠很好的說明一個函數就是一個範圍,那麼我們現在稍微改一下代碼看看情況?
age = 15def func(): print(‘第一層age:‘,age) # 第一層age: 15 def func2(): print("func2中的age:",age) # func2中的age: 15 # 看到沒有,如果當前範圍裡沒有age變數,那麼它就會往上找 def func3(): age = 84 print("func3中的age:",age) # func3中的age: 84 func3() # 調用func3函數 func2() # 調用func2函數func()
那麼,這時候有人就說了,屁話一大堆講的原來是局部變數和全域變數,那麼我想問:在上面這個嵌套函數中,func2中並沒有age變數,那麼它是如何找到全域變數age = 15的?
此時我們就需要來看一下範圍的尋找順序了:
變數範圍LEGB
- L:locals 函數內的名稱空間,包括局部變數和實參
- E:enclosing 外部嵌套函數的名稱空間,即相鄰的上一層,打個比方說:func2中沒有age變數則會去func裡找這個
- G:globals 全域變數
- B:builtins 內建模組的名稱空間
咳咳,還是先瞭解下什麼是名稱空間把?
名稱空間,又名name space,顧名思義就是存放名字的地方,存什麼名字呢?舉例說明,x = 1 ,1存放在記憶體當中,那麼變數名x存放在哪裡呢?名稱空間就是存放名字x與1綁定關係的地方
>>> x = 1>>> id(1)1576430608
名稱空間分為以下3種:
- locals: 是函數內的名稱空間,包括局部變數和形參
- globals: 全域變數,函數定義所在模組的名字空間
- builtins: 內建模組的名字空間
不同變數的範圍不同就是有這個變數所在的命名空間決定的.
範圍即範圍
- 全域範圍:全域存活,全域有效
- 局部範圍:臨時存貨,局部有效
讓我們來舉例看一下
level = ‘L0‘n = 22def func(): level = ‘L1‘ n = 33 print(locals()) # {‘n‘: 33, ‘level‘: ‘L1‘} def outer(): n = 44 level = ‘L2‘ print(locals(),n) # {‘level‘: ‘L2‘, ‘n‘: 44} 44 def inner(): level = ‘L3‘ print(locals(),n) # {‘level‘: ‘L3‘, ‘n‘: 44} 44 inner() outer()func()
以 L --> E --> G -->B 的規則尋找,即:在局部找不到,便會去局部外的局部找(例如閉包),再找不到就會去全域找,再者去內建函數中找。
python函數範圍