摘要:恩如期來啦閉包一函數作為返回值介紹閉包之前,先了解一下函數作為返回值的情況。例如之前介紹的裝飾器中,就出現了將函數作為返回值。當執行時,相當于執行,且包含。允許使用關鍵字創造匿名函數。例如調用默認可以把匿名函數作為返回值返回,例如
恩~ 如期來啦“閉包”~
介紹“閉包”之前,先了解一下函數作為返回值的情況。
高階函數除了可以接收函數作為參數外,還可以把函數作為結果值返回。例如之前介紹的裝飾器中,就出現了將函數作為返回值。
什么是閉包?
當在函數中嵌套另一個函數時,如果內部函數引用了外部函數的變量,則可能產生閉包。
所以閉包產生的三個條件(缺一不可):
1、必須嵌套一個內部函數
2、內部函數必須引用外部函數的變量
3、外部函數必須返回內部函數
那為什么要試用閉包,閉包的作用呢?
1、閉包可以根據外部函數的局部變量來得到不同的結果
2、當閉包執行完成后,仍可以保持當前的運行環境,執行結果依賴于該函數上一次的運行結果
2、閉包舉例栗子一:求序列之和
>>> def calc_sum(*args): ... ax = 0 ... for n in args: ... ax = ax + n ... return ax # 返回變量 ... >>> calc_sum(1,2,3) 6
但是,現在如果要求不需要立即取得求和結果,而是在后面的代碼中,根據需要再計算,該怎么弄呢?
我們可以不返回求和的結果,而返回求和的函數,如下:
>>>def lazy_sum(*args): ... def sum(): # sum()是內部函數,可以利用外部函數的參數 ... ax = 0 ... for n in args: # sum()中使用外部函數的局部變量 ... ax = ax + n ... return ax ... return sum # 形成閉包,此時,*args保存在返回的函數中 ... >>>f = lazy_sum(1,3,5,7,9) >>>f # 此時返回的是求和函數 >>> f() # 調用函數f()時,才真正計算求和的結果 25
注意:
lazy_sum()函數的內部執行順序,執行f時,運行到return sum處,*args保存在返回函數中,返回的是sum()函數。當執行f()時,相當于執行sum(),且包含*args。
當我們調用lazy_sun()時,每次都會返回一個新的函數,即使傳入相同的參數,但是f()調用結果不影響。
我們來驗證第二點:
# 但是調用 f1() 與f2()的調用結果互不影響 >>> f1 = lazy_sum(1,3,5,7,9) >>> f2 = lazy_sum(1,3,5,7,9) >>> f1.sum at 0x013DD618> >>> f2 .sum at 0x02F92DF8> >>> f1 == f2 False >>> f1() == f2() True >>> f1() 25 >>> f2() 25 >>> id(f1()) 1627215984 >>> id(f2()) 1627215984
說明:f1與f2返回函數的位置不一樣,所以f1==f2返回結果為False。
但是不影響最后的執行結果,f1()與f2()的執行結果均為25,且用id()進行查看,指向是同一塊區域。
栗子二:
def count(): fs = [] for i in range(1, 4): def f(): # 返回函數f()放在循環里 return i*i fs.append(f) return fs f1, f2, f3 = count()
實際執行結果為:f1=9 f2=9 f3=9
可能與實際想的([1,4,9])有點不一樣。因為f()函數放在了for循環里,只有當循環結束后,最后才返回i=3的執行結果9。
所以返回函數最好不要引用任何循環變量,或者說后續可能變化的量。那如何來修改呢?
def count(): def f(j): def g(): return j*j # 形成閉包 return g fs = [] for i in range(1, 4): fs.append(f(i)) # 一個i值進入后,f(i)立刻被執行,并加入到fs中 return fs f1, f2, f3 = count() # 返回函數g沒有引用j
最后結果:[1,4,9] 即f1=1 f2=4 f3=9
定義:匿名函數指一類無需定義標識符函數名的函數或者子程序。Python允許使用lambda關鍵字創造匿名函數。
語法:lambda 參數:表達式
或者 lambda 形參1,…,形參n : function(形參),入參1,…,入參n
注意:1、lambda函數可以接收任意多個參數并且返回單個表達式的值;
2、lambda中不能包含命令,返回的表達式不能超過一個。
優點:1、可以省去定義函數的過程,精簡代碼;
2、對于一些抽象的、不會重復使用的函數可以用lambda進行定義。
例子:
>>> list( map( lambda x: x*x ,[1,2,3] ) ) [1, 4, 9]
其中lamdba x : x*x 實現的是:def f(x): return x*x 的功能。
可以把匿名函數賦值給一個變量,再利用變量調用該函數。例如:
>>> f = lambda x:x*x >>> f(5) # 調用 >>> g = lambda x,y=2 : x*y >>> g(2,4) 8 >>> g(2) # 默認y=2 4
可以把匿名函數作為返回值返回,例如:
return lambda x:x*x
? thanks for watching, keep on updating...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/42474.html
摘要:閉包可以用來在一個函數與一組私有變量之間創建關聯關系。夾帶私貨外部變量返回的是函數,帶私貨的函數支持將函數當成對象使用的編程語言,一般都支持閉包。所以說當你的裝飾器需要自定義參數時,一般都會形成閉包。 Python中的閉包不是一個一說就能明白的概念,但是隨著你往學習的深入,無論如何你都需要去了解這么一個東西。 閉包的概念 我們嘗試從概念上去理解一下閉包。 在一些語言中,在函數中可以(嵌...
摘要:項目地址閉包在計算機科學中,閉包英語,又稱詞法閉包或函數閉包,是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即使已經離開了創造它的環境也不例外。 項目地址:https://git.io/pytips 閉包(Closure) 在計算機科學中,閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數閉包(function closures),是...
摘要:我們說觸發了閉包的函數叫做閉包函數閉包最大的特點就是它可以被外層函數返回后賦值給一個變量,并且攜帶了外層函數內定義的變量例子如下變量為函數開辟的局部命名空間內定義的變量函數內引用了變量的內層函數名被當作返回值,此時閉包規則達成。 什么是閉包? 其實我們在使用函數過程中不經意間就會觸發閉包,因為總會出于某種原因會在函數內引用或修改上一層函數的變量,這時就會觸發閉包 那么什么是閉包?其實就...
摘要:在計算機科學中,閉包又稱詞法閉包或函數閉包,是引用了自由變量的函數。閉包被廣泛應用于函數式語言中。運用閉包可以避免對全局變量的使用。將棧頂的元素取出,創建元組,并將該元組進棧。 在計算機科學中,閉包 又稱 詞法閉包 或 函數閉包,是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即使已經離開了創造它的環境也不例外。閉包被廣泛應用于函數式語言中。 從上面這段話中可以看出閉...
Python 中通過函數定義所創建的用戶自定義函數對象均具有一些特殊屬性,需要注意的是這里介紹的是自定義函數(function類型)的特殊屬性,而非方法(method 類型)的特殊屬性,函數和方法的特熟屬性以及默認的返回值可能不盡相同。 對于大多數特殊屬性,可以通過下面這個例子示范一下: class Test(): def func(self, v = dog): 這里演...
閱讀 3140·2021-11-19 09:40
閱讀 2437·2021-10-14 09:42
閱讀 1713·2021-09-22 15:34
閱讀 1450·2019-08-30 15:55
閱讀 784·2019-08-29 12:59
閱讀 418·2019-08-28 18:28
閱讀 1825·2019-08-26 13:42
閱讀 1531·2019-08-26 13:29