python中的閉包

來源:互聯網
上載者:User
什麼是閉包?

簡單說,閉包就是根據不同的配置資訊得到不同的結果

再來看看專業的解釋:閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變數的函數。這個被引用的自由變數將和這個函數一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。

python執行個體

看概念總是讓人摸不著頭腦,看幾個python小例子就會了

例1
def make_adder(addend):    def adder(augend):        return augend + addend    return adderp = make_adder(23)q = make_adder(44)print p(100)print q(100)
運行結果:
123144
分析一下:

我們發現,make_adder是一個函數,包括一個參數addend,比較特殊的地方是這個函數裡面又定義了一個新函數,這個新函數裡面的一個變數正好是外部make_adder的參數.也就是說,外部傳遞過來的addend參數已經和adder函數綁定到一起了,形成了一個新函數,我們可以把addend看做新函數的一個配置資訊,配置資訊不同,函數的功能就不一樣了,也就是能得到定製之後的函數.

再看看運行結果,我們發現,雖然p和q都是make_adder產生的,但是因為配置參數不同,後面再執行相同參數的函數後得到了不同的結果.這就是閉包.

例2
def hellocounter (name):    count=[0]     def counter():        count[0]+=1        print 'Hello,',name,',',str(count[0])+' access!'    return counterhello = hellocounter('ma6174')hello()hello()hello()  
執行結果
Hello, ysisl , 1 access!Hello, ysisl , 2 access!Hello, ysisl , 3 access!
分析一下

這個程式比較有趣,我們可以把這個程式看做統計一個函數調用次數的函數.count[0]可以看做一個計數器,沒執行一次hello函數,count[0]的值就加1。也許你會有疑問:為什麼不直接寫count而用一個列表?這是python2的一個bug,如果不用列表的話,會報這樣一個錯誤:

UnboundLocalError: local variable 'count' referenced before assignment.

什麼意思?就是說conut這個變數你沒有定義就直接引用了,我不知道這是個什麼東西,程式就崩潰了.於是,再python3裡面,引入了一個關鍵字:nonlocal,這個關鍵字是幹什麼的?就是告訴python程式,我的這個count變數是再外部定義的,你去外面找吧.然後python就去外層函數找,然後就找到了count=0這個定義和賦值,程式就能正常執行了.

python3 代碼

def hellocounter (name):    count=0     def counter():        nonlocal count        count+=1        print 'Hello,',name,',',str(count[0])+' access!'    return counterhello = hellocounter('ma6174')hello()hello()hello()  

關於這個問題的研究您可以參考http://linluxiang.iteye.com/blog/789946

例3
def makebold(fn):    def wrapped():        return "<b>" + fn() + "</b>"    return wrappeddef makeitalic(fn):    def wrapped():        return "<i>" + fn() + "</i>"    return wrapped@makebold@makeitalicdef hello():    return "hello world"print hello() 
執行結果
<b><i>hello world</i></b>
簡單分析

怎麼樣?這個程式熟悉嗎?這不是傳說的的裝飾器嗎?對,這就是裝飾器,其實,裝飾器就是一種閉包,我們再回想一下裝飾器的概念:對函數(參數,傳回值等)進行加工處理,產生一個功能增強版的一個函數。再看看閉包的概念,這個增強版的函數不就是我們配置之後的函數嗎?區別在於,裝飾器的參數是一個函數或類,專門對類或函數進行加工處理。

python裡面的好多進階功能,比如裝飾器,產生器,列表推到,閉包,匿名函數等,開發中用一下,可能會達到事半功倍的效果!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.