當前位置:  首頁  >  PHP教程  >  PHP 基礎  >  開發經驗

python中的閉包用法實例詳解

這篇文章主要介紹了python中的閉包用法,以實例形式詳細分析了Python中閉包的概念及相關使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
本文實例講述了python中的閉包用法。分享給大家供大家參考。具體分析如下:

什么是閉包?

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

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

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

希望本文所述對大家的Python程序設計有所幫助。

吐了個 "CAO" !
掃碼關注 PHP1 官方微信號
PHP1.CN | 中國最專業的PHP中文社區 | PHP資訊 | PHP教程 | 數據庫技術 | 服務器技術 | 前端開發技術 | PHP框架 | 開發工具 | PHP問答
Copyright ? 1998 - 2020 PHP1.CN. All Rights Reserved PHP1.CN 第一PHP社區 版權所有
     
28玩法