命名空間 從python解釋器開始執行之後,就在記憶體中開闢了一個空間,每當遇到一個變數的時候,就把變數名和值之間的對應關係記錄下來。但是當遇到函數定義的時候解釋器只是象徵性的將函數名讀入記憶體,表示知道這個函數的存在了,至於函數內部的變數和邏輯解釋器根本不關心。等執行到函數調用的時候,python解釋 ...
命名空間
從python解釋器開始執行之後,就在記憶體中開闢了一個空間,每當遇到一個變數的時候,就把變數名和值之間的對應關係記錄下來。但是當遇到函數定義的時候解釋器只是象徵性的將函數名讀入記憶體,表示知道這個函數的存在了,至於函數內部的變數和邏輯解釋器根本不關心。等執行到函數調用的時候,python解釋器會再開闢一塊記憶體來存儲這個函數里的內容,這個時候,才關註函數裡面有哪些變數,而函數中的變數會存儲在新開闢出來的記憶體中。函數中的變數只能在函數的內部使用,並且會隨著函數執行完畢,這塊記憶體中的所有內容也會被清空。
存放名字與值的關係”的空間起了一個名字——叫做命名空間
代碼在運行伊始,創建的存儲“變數名與值的關係”的空間叫做全局命名空間,在函數的運行中開闢的臨時的空間叫做局部命名空間。
命名空間一共分為三種:
全局命名空間
局部命名空間
內置命名空間
內置命名空間中存放了python解釋器為我們提供的名字:input,print,str,list,tuple...它們都是我們熟悉的,拿過來就可以用的方法。
三種命名空間之間的載入與取值順序:
載入順序:內置命名空間(程式運行前載入)->全局命名空間(程式運行中:從上到下載入)->局部命名空間(程式運行中:調用時才載入)
在局部調用:局部命名空間->全局命名空間->內置命名空間
x = 1
def f(x):
print(x)
print(10)
在全局調用:全局命名空間->內置命名空間
x = 1
def f(x):
print(x)
f(10)
print(x)
作用域
作用域就是作用範圍,按照生效範圍可以分為全局作用域和局部作用域。
全局作用域:包含內置名稱空間、全局名稱空間,在整個文件的任意位置都能被引用、全局有效
局部作用域:局部名稱空間,只能在局部範圍內生效
global關鍵字
a = 10
def func():
global a
a = 20
print(a)
func()
print(a)
通過global 在函數中修改全局變數,global必須聲明在前面。
函數的作用域鏈
例子1
def f1():
a = 1
def f2():
print(a)
f2()
f1()
例子2
def f1():
a = 1
def f2():
def f3():
print(a)
f3()
f2()
f1()
例子3
def f1():
a = 1
def f2():
a = 2
f2()
print('a in f1 : ',a)
f1()
nonlocal關鍵字
- 外部必須有這個變數
- 在內部函數聲明nonlocal變數之前不能再出現同名變數
- 內部修改這個變數如果想在外部有這個變數的第一層函數中生效
根據上面例子3進行修改代碼
def f1():
a = 1
def f2():
nonlocal a
a = 2
f2()
print('a in f1 : ',a)
f1()
函數名的本質
函數名本質上就是函數的記憶體地址
1.可以被引用
通過賦值,函數記憶體地址都是相同的,接下來print(f)會出現什麼呢?
只會列印出記憶體地址,因為我們沒有進行調用函數
<function func at 0x00000201444B4C80>
下麵修改成print(f())再看看,結果出現
in func
None
因為f()沒有返回值,所以調用函數後先輸出in func再列印沒有返回值的函數就會出現None,所以直接f()就行了
當代碼修改成下麵這樣就可以print(f())
2.可以被當作容器類型的元素
def f1():
print('f1')
def f2():
print('f2')
def f3():
print('f3')
l = [f1,f2,f3]
d = {'f1':f1,'f2':f2,'f3':f3}
#調用
l[0]()
d['f2']()
3.可以當作函數的參數和返回值
不明白?那就記住一句話,就當普通變數用!