欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

簡單講解Python中的閉包

系統 1610 0

閉包并不是什么新奇的概念,它早在高級語言開始發展的年代就產生了。閉包(Closure)是詞法閉包(Lexical Closure)的簡稱。對閉包的具體定義有很多種說法,這些說法大體可以分為兩類:
一種說法認為閉包是符合一定條件的函數,比如參考資源中這樣定義閉包:閉包是在其詞法上下文中引用了自由變量的函數。
另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。比如參考資源中就有這樣的的定義:在實現深約束時,需要創建一個能顯式表示引用環境的東西,并將它與相關的子程序捆綁在一起,這樣捆綁起來的整體被稱為閉包。

就像這樣:

            
#python 中的閉包
... def func(data):
...   count = [data]
...   def wrap():
...     count[0] += 1
...     return count[0]
...   return wrap
... 
... a = func(1)
>>> a()
5: 2
>>> a()
6: 3

 def func(x):
...   return lambda y :y+x
>>> b = func(1)
>>> b(1)
7: 2
>>> b(2)
8: 3
>>> print b #這里b是個function 在ruby中是proc

            
              
                 at 0x01AC68F0>


 def addx(x):
... def adder (y): return x + y
... return adder
>>> add8 = addx(8)
>>> add8(8)
9: 16


              
            
          

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

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

例1

            
def make_adder(addend):
  def adder(augend):
    return augend + addend
  return adder

p = make_adder(23)
q = make_adder(44)

print p(100)
print q(100)


          

運行結果:

            
123
144

          

分析一下:
我們發現,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 counter

hello = 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 counter

hello = hellocounter('ma6174')
hello()
hello()
hello() 



          

例3

            
def makebold(fn):
  def wrapped():
    return "
            
              " + fn() + "
            
            "
  return wrapped

def makeitalic(fn):
  def wrapped():
    return "
            
              " + fn() + "
            
            "
  return wrapped

@makebold
@makeitalic
def hello():
  return "hello world"

print hello() 


          

執行結果

            
              
                hello world
              
            
          

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

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



更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 天天艹夜夜 | 国产精品一区二区三区四区 | 国产精品无码人妻无码色情多人 | 啪啪成人| 亚洲精品久久久久一区二区 | 激情视频在线观看网站 | 欧美高清视频一区 | 日本亚洲一区二区 | 91精品国产综合久久婷婷香蕉 | 成人无码T髙潮喷水A片小说 | 日韩一区免费在线观看 | 青娱乐免费视频观看 | 久久久久网站 | 午夜久久视频 | 亚洲黄色第一页 | 羞羞的视频在线免费观看 | 亚洲成人小视频 | 亚洲成片在线观看12345ba | 欧美久久xxxxxx影院 | 欧美一区二区三区在线看 | 日韩毛片网 | 欧美va在线视频 | 久久最新精品 | 苏晓晖个人简介军衔 | 欧美剧场成人精品午夜 | 99久久99久久免费精品蜜桃 | 色欧美色| 一级毛片免费不卡在线 | 爱爱视频在线观看 | 国产精品福利视频免费观看 | 亚洲最黄视频 | 91短视频在线高清hd | 最新国产精品 | 成人午夜精品 | 日韩亚洲一区二区三区 | 欧美 日韩 | 精品一区二区在线观看视频 | 成人福利在线观看 | 日韩在线精品 | 国产高清在线视频 | 91精品国模一区二区三区 |