python 函數語言程式設計-閉包
阿新 • • 發佈:2020-08-08
1、基礎知識保證我們寫出業務程式碼,而且我們不考慮太多的封裝性;高階知識保證,可以去更好的封裝包,類庫,提供給其他人使用
2、高階知識
- 函數語言程式設計
- 閉包
- 什麼是函數語言程式設計?
- 什麼是閉包?
3、python中一切結皆物件。所以函式也是物件。
- 函式可以賦值給一個變數,變數的型別是個函式function
-
def curve_pre(): pass a = curve_pre print(type(a)) # [Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test20.py" # <type 'function'>
- 呼叫函式變數,執行該函式,返回的該函式計算結果
-
def curve_pre(): def curve(x): return x*x return curve f = curve_pre() print(f)#返回的是一個函式&函式可以賦值給一個變數 print(f(2))#呼叫返回的函式 # [Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test20.py" # <function curve at 0x1078b0140> # 4
- 變數a從內到外層找,逐漸從小作用域到大作用域去找,從精確作用域到概括作用域,即優先順序從內層函式區域性變數->外層函式區域性變數->最外層變數
-
a = 100#3、外層沒有,去更外層找 def curve_pre(): a = 50#2、沒有內層a,去外層找a def curve(x): a = 1#1、先找這個a return a*x*x return curve f = curve_pre() print(f) print(f(2))
由此引入什麼是閉包?閉包=函式+環境變數,把a定義在標誌1的位置,也就是函式內部,不叫閉包,頂多算個函式呼叫,定義在函式的外部,也就是3的位置,那也不叫閉包
- 放在內層2的位置,為什麼叫閉包?
def curve_pre(): a
改了a=1,也不起作用,前面說過的使用優先順序。注意閉包的內容,f.__closure__,是把函式呼叫的現場給儲存下來了,閉包=函式+環境變數(a=50,func=curve)
- 函式閉包的需要注意什麼?
-
def f0(): a = 50 def f1(x): a=1#造成了不是閉包,閉包=環境變數(f0()層定義的a=50)+函式f1(x) return a*x*x return f1 f = f0() print(f.__closure__) print(f.__closure__[0].cell_contents) print(f(2)) # [Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test21.py" # None # Traceback (most recent call last): # File "/Users/anson/Documents/Project/python_ToolCodes/test21.py", line 10, in <module> # print(f.__closure__[0].cell_contents) # TypeError: 'NoneType' object has no attribute '__getitem__'
正確的做法是,不要再內層定義a,這樣就沒有環境變量了!!!!!!,閉包的2個必要元素缺少一個了,怎麼還會是閉包!!!!!!
-
def f0(): a = 50 def f1(x): c=1 return a*x*x return f1 f = f0() print(f.__closure__) print(f.__closure__[0].cell_contents) print(f(2)) # [Running] python -u "/Users/anson/Documents/Project/python_ToolCodes/test21.py" # (<cell at 0x10a3df750: int object at 0x7f963de06158>,) # 50 # 200
這樣改或者註釋掉f1(x)中定義的a 就可以了
- 閉包是用來幹什麼的,使用場景是什麼?
- 計算旅行者當前所處的位置,起點origin=0
非閉包 origin = 0 def go(step): global origin #宣告origin為gloabl,記錄旅行者當前的位置 new_pos = origin+step origin = new_pos return new_pos print(go(3)) print(go(2)) 輸出: 3 5
閉包 origin = 0 def go_pre(pos): def go(step): nonlocal pos#宣告pos 為 nonlocal new_pos = pos + step pos = new_pos return new_pos return go f = go_pre(origin) print(f(3)) print(f(2)) 輸出 3 5 ⚠️python2沒有nonlocal,python3才有
- 閉包主要用在Javascript 和python python 中強調的是閉包中的環境變數。