Python中的閉包

本文作者:黎智煊押搪,叩丁狼高級講師。原創(chuàng)文章浅碾,轉載請注明出處大州。

什么是閉包?閉包有什么用垂谢?為什么要用閉包厦画?今天我們就帶著這3個問題來一步一步認識閉包。閉包和函數(shù)緊密聯(lián)系在一起滥朱,介紹閉包前有必要先介紹一些背景知識根暑,諸如嵌套函數(shù)、變量的作用域等概念

  1. 作用域

    作用域是程序運行時變量可被訪問的范圍徙邻,定義在函數(shù)內(nèi)的變量是局部變量购裙,局部變量的作用范圍只能是函數(shù)內(nèi)部范圍內(nèi),它不能在函數(shù)外引用鹃栽。

    def foo():
    num = 10 # 局部變量
    print(num)  # NameError: name 'num' is not defined
    
    

    定義在模塊最外層的變量是全局變量躏率,它是全局范圍內(nèi)可見的,當然在函數(shù)里面也可以讀取到全局變量的民鼓。例如:

    num = 10 # 全局變量
    def foo():
    print(num)  # 10
    
    
  2. 嵌套函數(shù)

    函數(shù)不僅可以定義在模塊的最外層薇芝,還可以定義在另外一個函數(shù)的內(nèi)部,像這種定義在函數(shù)里面的函數(shù)稱之為嵌套函數(shù)(nested function)例如:

    def print_msg():
     # print_msg 是外圍函數(shù)
     msg = "zen of python"
    
     def printer():
         # printer是嵌套函數(shù)
         print(msg)
     printer()
    # 輸出 zen of python
    print_msg()
    
    

    對于嵌套函數(shù)丰嘉,它可以訪問到其外層作用域中聲明的非局部(non-local)變量夯到,比如代碼示例中的變量 msg 可以被嵌套函數(shù) printer 正常訪問。

那么有沒有一種可能即使脫離了函數(shù)本身的作用范圍饮亏,局部變量還可以被訪問得到呢耍贾?答案是閉包

什么是閉包

函數(shù)身為第一類對象阅爽,它可以作為函數(shù)的返回值返回,現(xiàn)在我們來考慮如下的例子:

def print_msg():
    # print_msg 是外圍函數(shù)
    msg = "zen of python"
    def printer():
        # printer 是嵌套函數(shù)
        print(msg)
    return printer

another = print_msg()
# 輸出 zen of python
another()

這段代碼和前面例子的效果完全一樣荐开,同樣輸出 “zen of python”付翁。不同的地方在于內(nèi)部函數(shù) printer 直接作為返回值返回了。

一般情況下晃听,函數(shù)中的局部變量僅在函數(shù)的執(zhí)行期間可用百侧,一旦 print_msg() 執(zhí)行過后,我們會認為 msg變量將不再可用能扒。然而佣渴,在這里我們發(fā)現(xiàn) print_msg 執(zhí)行完之后,在調(diào)用 another 的時候 msg 變量的值正常輸出了初斑,這就是閉包的作用辛润,閉包使得局部變量在函數(shù)外被訪問成為可能。

為什么要使用閉包

閉包避免了使用全局變量,此外,閉包允許將函數(shù)與其所操作的某些數(shù)據(jù)(環(huán)境)關連起來甜攀。這一點與面向對象編程是非常類似的,在面對象編程中晦溪,對象允許我們將某些數(shù)據(jù)(對象的屬性)與一個或者多個方法相關聯(lián)瀑粥。

一般來說挣跋,當對象中只有一個方法時,這時使用閉包是更好的選擇狞换。來看一個例子:

def adder(x):
    def wrapper(y):
        return x + y
    return wrapper

adder5 = adder(5)
# 輸出 15
adder5(10)
# 輸出 11
adder5(6)

這比用類來實現(xiàn)更優(yōu)雅避咆,此外裝飾器也是基于閉包的一中應用場景。

所有函數(shù)都有一個 closure屬性修噪,如果這個函數(shù)是一個閉包的話查库,那么它返回的是一個由 cell 對象 組成的元組對象。cell 對象的cell_contents 屬性就是閉包中的自由變量黄琼。

>>> adder.__closure__
>>> adder5.__closure__
(<cell at 0x103075910: int object at 0x7fd251604518>,)
>>> adder5.__closure__[0].cell_contents
5

這解釋了為什么局部變量脫離函數(shù)之后樊销,還可以在函數(shù)之外被訪問的原因的,因為它存儲在了閉包的 cell_contents中了脏款。

想獲取更多技術視頻围苫,請前往叩丁狼官網(wǎng):http://www.wolfcode.cn/openClassWeb_listDetail.html

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市撤师,隨后出現(xiàn)的幾起案子剂府,更是在濱河造成了極大的恐慌,老刑警劉巖剃盾,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腺占,死亡現(xiàn)場離奇詭異淤袜,居然都是意外死亡,警方通過查閱死者的電腦和手機衰伯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門铡羡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嚎研,你說我怎么就攤上這事蓖墅。” “怎么了临扮?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵论矾,是天一觀的道長。 經(jīng)常有香客問我杆勇,道長贪壳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任蚜退,我火速辦了婚禮闰靴,結果婚禮上,老公的妹妹穿的比我還像新娘钻注。我一直安慰自己蚂且,他們只是感情好,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布幅恋。 她就那樣靜靜地躺著杏死,像睡著了一般。 火紅的嫁衣襯著肌膚如雪捆交。 梳的紋絲不亂的頭發(fā)上淑翼,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音品追,去河邊找鬼玄括。 笑死,一個胖子當著我的面吹牛肉瓦,可吹牛的內(nèi)容都是我干的遭京。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼泞莉,長吁一口氣:“原來是場噩夢啊……” “哼哪雕!你這毒婦竟也來了?” 一聲冷哼從身側響起戒财,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤热监,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后饮寞,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體孝扛,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡列吼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了苦始。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寞钥。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖陌选,靈堂內(nèi)的尸體忽然破棺而出理郑,到底是詐尸還是另有隱情,我是刑警寧澤咨油,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布您炉,位于F島的核電站,受9級特大地震影響役电,放射性物質發(fā)生泄漏赚爵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一法瑟、第九天 我趴在偏房一處隱蔽的房頂上張望冀膝。 院中可真熱鬧,春花似錦霎挟、人聲如沸窝剖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赐纱。三九已至,卻和暖如春采郎,著一層夾襖步出監(jiān)牢的瞬間千所,已是汗流浹背狂魔。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工蒜埋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人最楷。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓整份,卻偏偏與公主長得像,于是被迫代替她去往敵國和親籽孙。 傳聞我的和親對象是個殘疾皇子烈评,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 什么是閉包?閉包有什么用犯建?為什么要用閉包讲冠?今天我們就帶著這3個問題來一步一步認識閉包。 閉包和函數(shù)緊密聯(lián)系在一起适瓦,...
    碼農(nóng)小楊閱讀 359評論 0 2
  • 這兩天學習的時候對python中的閉包產(chǎn)生了興趣竿开,網(wǎng)上這篇文章寫得很好谱仪,寫在這里大家看看。 1. 閉包的概念 首...
    Alistair閱讀 258評論 0 0
  • 目錄 作用域(scope) 閉包的定義 閉包的作用 總結 2018.4.15更新了對于函數(shù)作用域的理解內(nèi)容 1.作...
    苦逼李閱讀 681評論 1 0
  • 導讀:Python中的裝飾器經(jīng)常用于有切面需求的場景,較為經(jīng)典的有插入日志列荔、性能測試敬尺、事務處理等。本文從閉包的概念...
    zgjx閱讀 438評論 0 3
  • (一) 我不希望你因我而變贴浙, 更不希望你對我一成不變砂吞。 (二) 有的人愿意為愛而瘋狂, 我更喜歡安寧直到天黑崎溃。 (...
    紫色領結閱讀 711評論 2 5