摘要:作用域閉包裝飾器話聊上篇聽講一切都是對象,是嗎是的,像函數(shù)也是對象。不錯嘛這都被你看出來了,那你知道作用域的原則嗎我知道是知道可以我就是對那個作用域不是很理解。如果內部函數(shù)引用到外層函數(shù)作用域的對象,這個內部函數(shù)就稱為閉包。
Python Enclosing作用域、閉包、裝飾器話聊上篇
Jaglawz: 聽講Python一切都是對象,是嗎?
Pylego: 是的,像函數(shù)也是對象。
Jaglawz: 那么函數(shù)也可以有自己的屬性了?
Pylego: 當然,像下面這樣寫是可以的:
def foo(): print("I am foo") def bar(): print("I am bar") foo.bar = bar foo.bar()
Jaglawz: 這都行,那是不是函數(shù)也可以像普通對象一樣當作參數(shù)傳遞也可以當作對象來返回?
Pylego: 是的,比如下面的用法:
def deco(func): string = "I am deco" def wrapper(): print(string) func() return wrapper def foo(): print("I am foo") foo = deco(foo) foo() """ 輸出: I am deco Iam foo """
Jaglawz: 好吧,當作參數(shù)傳遞和返回我理解了,但是我對wrapper函數(shù)的print(string)這個string的查找感到迷惑。
Pylego: 不錯嘛!這都被你看出來了,那你知道Python作用域的LEGB原則嗎?
Jaglawz: 我知道是知道可以我就是對那個E(Enclosing)作用域不是很理解。
Pylego: 那就對了,你可以在剛才代碼的基礎上運行下面的代碼:
print(foo.__closure__) # 輸出:(, | ) |
Jaglawz: 咦,這兩個內存地址是啥家伙?
Pyelgo: 這就是wrapper函數(shù)引用的外層函數(shù)(就是deco函數(shù)啦)的兩個變量:string和func?。?/p>
Jaglawz: 也就是說內層函數(shù)(在本例中就是wrapper啦)會把外層函數(shù)(在本例用就是deco啦)作用域里面的對象放到__closure__屬性里,以供自己查找?
Pylego: 是的,但是不是所有外層函數(shù)作用域的對象都會放到內層函數(shù)的__closure__屬性里,僅限自己用到的,這個__closure__就是enclosing作用域啦!
Jaglawz: 原來enclosing作用域是這樣的,明白了。
Pyelgo: 如果內部函數(shù)引用到外層函數(shù)作用域的對象,這個內部函數(shù)就稱為閉包。
Jaglawz: 原來閉包就是這家伙,很簡單嘛!
Jaglawz: 咦,我想到內部函數(shù)有一個妙用,你看看是不是這樣啊,比如說我想輸出一個函數(shù)的運行時間又不想去破壞這個函數(shù)的代碼,是不是可以這樣寫:
import time def time_machine(func): def wrapper(*args, **kwargs): start_time = time.time() func(*args, **kwargs) print(u"共耗時: %s秒" % (time.time()-start_time)) return wrapper def foo(): time.sleep(3) foo = time_machine(foo) foo()
Pylego: 你這智商要沖出宇宙的節(jié)奏??!但是Python的開發(fā)者早就想到每次foo = time_machine(foo)很麻煩,特地為你準備了語法糖,來接糖:
import time def time_machine(func): def wrapper(*args, **kwargs): start_time = time.time() func(*args, **kwargs) print(u"共耗時: %s秒" % (time.time()-start_time)) return wrapper @time_machine def foo(): time.sleep(3) """ 也就是說: @time_machine def foo(): pass 相當于: foo = time_machine(foo),這里是重點,這里是重點,這里是重點,以后的談話能不能理解就看你對這個語句可理解! """ foo()
Pylego: time_machine就是裝飾器(decorator),名字起得多形象啊,裝飾函數(shù)嘛!
Jaglawz: 你這么一說,我就覺得裝飾器咋這么簡單呢!問題是我看到很多人的裝飾器還帶參數(shù),還有人用類當裝飾器,這又是咋回事呢?
Pylego: 你問題咋恁些?我先吃個飯,下次有空再聊哈!
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/45493.html
摘要:作用域閉包裝飾器話聊下篇作用域閉包裝飾器的基礎篇,請看作用域閉包裝飾器話聊上篇我經(jīng)??吹接腥说难b飾器是帶參數(shù)的,這又是咋回事呢這個其實很簡單的,你還記得上次我說相當于那么相當于也就是說,返回的是一個裝飾器函數(shù),然后再去裝飾其他函數(shù)。 Python Enclosing作用域、閉包、裝飾器話聊下篇 Python Enclosing作用域、閉包、裝飾器的基礎篇,請看Python Enclos...
摘要:在計算機科學中,閉包又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。閉包被廣泛應用于函數(shù)式語言中。運用閉包可以避免對全局變量的使用。將棧頂?shù)脑厝〕觯瑒?chuàng)建元組,并將該元組進棧。 在計算機科學中,閉包 又稱 詞法閉包 或 函數(shù)閉包,是引用了自由變量的函數(shù)。這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。閉包被廣泛應用于函數(shù)式語言中。 從上面這段話中可以看出閉...
摘要:變量查找規(guī)則在中一個變量的查找順序是局部環(huán)境,閉包,全局,內建閉包引用了自由變量的函數(shù)。閉包的作用閉包的最大特點是可以將父函數(shù)的變量與內部函數(shù)綁定,并返回綁定變量后的函數(shù),此時即便生成閉包的環(huán)境父函數(shù)已經(jīng)釋放,閉包仍然存在。 導語:本文章記錄了本人在學習Python基礎之函數(shù)篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。 本文重點: 1、掌握裝飾器的本質、功...
摘要:迭代器迭代是訪問集合元素的一種方式。迭代器是一個可以記住遍歷的位置的對象,迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束,迭代器只往前不會往后退。生成器特點保存了一套生成數(shù)值的算法。 迭代器 迭代是訪問集合元素的一種方式。迭代器是一個可以記住遍歷的位置的對象,迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束,迭代器只往前不會往后退。 可迭代對象 以直接...
摘要:在嵌套函數(shù)中訪問了最外層函數(shù)的參數(shù),結果我們是能正常訪問閉包我們將上面的最外層的返回值修改為返回嵌套函數(shù)的引用一切皆對象根據(jù)前面變量生存期例子,按理說調用完的生命周期應該結束了,調用應該失敗才對,但是實際卻調用成功了。 復習 python引用變量的順序: 當前作用域局部變量 -> 外層作用域變量 -> 當前模塊中的全局變量 -> python內置變量 global:聲明一個全局變量 n...
閱讀 2901·2021-11-24 09:39
閱讀 2470·2019-08-30 15:53
閱讀 3038·2019-08-30 13:47
閱讀 1327·2019-08-30 12:50
閱讀 1491·2019-08-29 16:31
閱讀 2653·2019-08-29 13:14
閱讀 1571·2019-08-29 10:55
閱讀 804·2019-08-26 13:32