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