一:爲何要有命名空間?python
兩個函數求最大值,return函數的最大值,並將它打印出來了,那麼能直接打印嗎?看下面的函數函數
eg1:this
def max(x,y): z=x if x>y else y return z bigger=max(16,20) print(bigger)
打印結果:20內存
若是是這樣呢?作用域
eg2:cmd
def max(x,y): z=x if x>y else y max(16,20) print(z)
打印結果:import
爲何會報錯?變量
由於咱們進行打印,打印的是全局變量,內部變量z沒有被定義,全局變量不能引用內部變量。命名空間
也就是說:引用
從python解釋器開始執行的時候,就在內存開闢出了一個空間。
沒遇到一個變量就會把變量名和值的對應關係記錄下來。
可是當遇到函數定義的時候,python解釋器只是象徵性的將函數關心讀入內存(表示則這個函數已經存在,至於內部邏輯和變量解釋器並不關心)
等到函數調用的時候,python解釋器會在內存中再開闢一個內存來存儲函數裏面內容, 這個時候,才關注函數裏面有哪些變量,而函數中的變量會存儲在新開闢出來的內存中。函數中的變量只能在函數的內部使用,而且會隨着函數執行完畢,這塊內存中的全部內容也會被清空。
這個存放名字與值的關係的空間就是命名空間
代碼從運行開始,建立的存儲名字和值的關係空間就是全局命名空間,而在函數運行過程當中臨時開闢空間就是局部命名空間。
二:命名空間的本質:存放名字與值的綁定關係
python之禪:
打開cmd命令在python解釋器中輸入import this
三:命名空間種類
內置命名空間 全局命名空間 局部命名空間
內置命名空間:存放python解釋器提供的關鍵字:sum,print,str,list等50多種內置關鍵字。
四:三種命名空間的加載和取值順序
加載順序:
內置(程序運行前加載)----全局(程序運行中,從上到下加載)-----局部(程序運行中,調用才加載)
取值順序:
在局部中:
局部--全局---局部(兒子能夠花老子的錢,老子不能花兒子錢)
a=1 def max(): a=2 return a rr=max() print(rr) print(a)
打印結果:2,1
在全局:全局---局部
x = 1 def f(x): print(x) f(10) print(x)
打印結果:10,1
四:做用域
做用域就是做用範圍,按照生效範圍可分爲全局做用域和局部做用域
全局做用域:包括全局命名空間和內置命名空間,整個文件任意位置被引用,全局生效。
局部做用域:只在局部命名空間內,局部範圍有效。
globals和locals
def func(): a = 12 b = 20 print(locals()) print(globals()) func()
打印結果
global:聲明函數在全局有效
a = 10 def func(): global a a = 20 print(a) print(a) func() print(a)
他的執行順序
執行結果:
函數嵌套調用:
def max2(x,y): m = x if x>y else y return m def max4(a,b,c,d): res1 = max2(a,b) res2 = max2(res1,c) res3 = max2(res2,d) return res3 print(max4(23,-7,31,11)) print(max2(10,20))
顯示結果:
函數的嵌套定義
eg1:
def f1(): print("in f1") def f2(): print("in f2") f2() f1()
eg2:
def f1(): def f2(): def f3(): print("in f3") print("in f2") f3() print("in f1") f2() f1()
函數的做用域鏈
def f1(): a = 1 def f2(): a = 2 f2() print('a in f1 : ',a) f1()
global適用於函數內部修改全局變量的值
nonlocal適用於嵌套函數中內部函數修改外部變量的值
def f1(): a = 1 def f2(): nonlocal a a = 2 f2() print('a in f1 : ',a) f1()
打印結果:2
'a in f1 : ',2