本篇內容主要講解“Python閉包的概念、形式與應用方式”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Python閉包的概念、形式與應用方式”吧!
閉包(Closure)是詞法閉包(Lexical Closure)的簡稱。對閉包的具體定義有很多種說法,這些說法大體可以分為兩類:
◆一種說法認為閉包是符合一定條件的函數,比如參考資源中這樣定義閉包:閉包是在其詞法上下文中引用了自由變量的函數。
◆另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。比如參考資源中就有這樣的的定義:在實現深約束時,需要創建一個能顯式表示引用環境的東西,并將它與相關的子程序捆綁在一起,這樣捆綁起來的整體被稱為閉包。
這兩種定義在某種意義上是對立的,一個認為閉包是函數,另一個認為閉包是函數和引用環境組成的整體。雖然有些咬文嚼字,但可以肯定第二種說法更確切。閉包只是在形式和表現上像函數,但實際上不是函數。函數是一些可執行的代碼,這些代碼在函數被定義后就確定了,不會在執行時發生變化,所以一個函數只有一個實例。
閉包在運行時可以有多個實例,不同的引用環境和相同的函數組合可以產生不同的實例。所謂引用環境是指在程序執行中的某個點所有處于活躍狀態的約束所組成的集合。其中的約束是指一個變量的名字和其所代表的對象之間的聯系。那么為什么要把引用環境與函數組合起來呢?這主要是因為在支持嵌套作用域的語言中,有時不能簡單直接地確定函數的引用環境。
閉包和函數對象本質上是同一種東西,閉包是函數對象的簡化。閉包將環境數據保存在func_closure中,函數對象則將相關數據保存在對象中。二者均可用于filter、map、reduce等函數中。
下面分別使用閉包和函數對象來做同一件事情,感覺二者非常相似。
?[Copy to clipboard]View Code PYTHONIn [68]: class counter_class(): def __init__(self, start_at): self.start_at = start_at def __call__(self): self.start_at += 1 return self.start_at ....: ....: In [74]: In [75]: c1 = counter_class(5) In [76]: c1() Out[76]: 6 In [77]: c1() Out[77]: 7 In [78]: c1() Out[78]: 8
In [80]: def counter_closure(start_at = 0): count = [start_at] def incr(): count[0] += 1 return count[0] return incr ....: In [86]: c2 = counter_closure(5) In [87]: c2() Out[87]: 6 In [88]: c2() Out[88]: 7 In [89]: c2() Out[89]: 8
支持閉包的語言有這樣的特性:
1、函數是一階值(First-class value),即函數可以作為另一個函數的返回值或參數,還可以作為一個變量的值。
2、函數可以嵌套定義,即在一個函數內部可以定義另一個函數。
顯然Python對這兩個特性支持都非常好,Java要想支持閉包改動就有點大了。在Python中函數同類差不多,而在Java中類是最小的組織單元,目前JDK 6.0上面兩個特性一個都不支持。至于C++這樣更底層的語言要支持閉包估計是不可能的。
Python中的閉包
Python因其簡單易學、功能強大而擁有很多擁護者,很多企業和組織在使用這種語言。Python使用縮進來區分作用域的做法也十分有特點。下面是一個Python的例子:
清單 6. Python 1 def addx(x): def adder (y): return x + y return adder add8 = addx(8) add9 = addx(9) print add8(100) print add9(100)
在Python中使用def來定義函數時,是必須有名字的,要想使用匿名函數,則需要使用lambda語句,象下面的代碼這樣:
清單 7. Python 2 def addx(x): return lambda y: x + y add8 = addx(8) add9 = addx(9) print add8(100) print add9(100)
到此,相信大家對“Python閉包的概念、形式與應用方式”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。