最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

簡析Python的閉包和裝飾器

 更新時間:2021年06月07日 14:26:45   作者:xu_zhoufeng  
這篇文章主要為大家詳細介紹了Python的閉包和裝飾器,何為閉包?何為裝飾器?感興趣的小伙伴們可以參考一下

什么是裝飾器?

裝飾器(Decorator)相對簡單,咱們先介紹它:“裝飾器的功能是將被裝飾的函數(shù)當(dāng)作參數(shù)傳遞給與裝飾器對應(yīng)的函數(shù)(名稱相同的函數(shù)),并返回包裝后的被裝飾的函數(shù)”,聽起來有點繞,沒關(guān)系,直接看示意圖,其中 a 為與裝飾器 @a 對應(yīng)的函數(shù), b 為裝飾器修飾的函數(shù),裝飾器@a的作用是:

簡而言之:@a 就是將 b 傳遞給 a(),并返回新的 b = a(b)

栗子:

上面使用@dobi來表示裝飾器,其等同于:qinfeng = dobi(qinfeng)
因此裝飾器本質(zhì)上就是個語法糖,其作用為簡化代碼,以提高代碼可讀性,運行上段代碼的結(jié)果為:

解析過程是這樣子的:

1.python 解釋器發(fā)現(xiàn)@dobi,就去調(diào)用與其對應(yīng)的函數(shù)( dobi 函數(shù))
2.dobi 函數(shù)調(diào)用前要指定一個參數(shù),傳入的就是@dobi下面修飾的函數(shù),也就是 qinfeng()
3.dobi() 函數(shù)執(zhí)行,調(diào)用 qinfeng(),qinfeng() 打印“dobi”

什么是閉包?

首先還得從基本概念說起,什么是閉包呢?來看下維基上的解釋:
在計算機科學(xué)中,閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數(shù)。這個被引用的自由變量將和這個函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。所以,有另一種說法認為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實體。閉包在運行時可以有多個實例,不同的引用環(huán)境和相同的函數(shù)組合可以產(chǎn)生不同的實例。

....

上面提到了兩個關(guān)鍵的地方: 自由變量 和 函數(shù), 這兩個關(guān)鍵稍后再說。還是得在贅述下“閉包”的意思,望文知意,可以形象的把它理解為一個封閉的包裹,這個包裹就是一個函數(shù),當(dāng)然還有函數(shù)內(nèi)部對應(yīng)的邏輯,包裹里面的東西就是自由變量,自由變量可以在隨著包裹到處游蕩。當(dāng)然還得有個前提,這個包裹是被創(chuàng)建出來的。
在通過Python的語言介紹一下,一個閉包就是你調(diào)用了一個函數(shù)A,這個函數(shù)A返回了一個函數(shù)B給你。這個返回的函數(shù)B就叫做閉包。你在調(diào)用函數(shù)A的時候傳遞的參數(shù)就是自由變量。

舉個栗子:

def func(name):
  def inner_func(age):
    print 'name:', name, 'age:', age
  return inner_func

bb = func('the5fire')
bb(26) # >>> name: the5fire age: 26

這里面調(diào)用func的時候就產(chǎn)生了一個閉包——inner_func,并且該閉包持有自由變量——name,因此這也意味著,當(dāng)函數(shù)func的生命周期結(jié)束之后,name這個變量依然存在,因為它被閉包引用了,所以不會被回收。

另外再說一點,閉包并不是Python中特有的概念,所有把函數(shù)做為一等公民的語言均有閉包的概念。不過像Java這樣以class為一等公民的語言中也可以使用閉包,只是它得用類或接口來實現(xiàn)。

nonlocal 語句

在 python 的函數(shù)內(nèi),可以直接引用外部變量,但不能改寫外部變量,因此如果在閉包中直接改寫父函數(shù)的變量,就會發(fā)生錯誤:

在 python 2 中可以在函數(shù)內(nèi)使用 global 語句,但全局變量在任何語言中都不被提倡,因為它很難控制,python 3 中引入了 nonlocal 語句解決了這個問題:

Nonlocal 與 global 的區(qū)別在于 nonlocal 語句會去搜尋本地變量與全局變量之間的變量,其會優(yōu)先尋找層級關(guān)系與閉包作用域最近的外部變量。

閉包與裝飾器

上面已經(jīng)簡單演示了裝飾器的功能,事實上,裝飾器就是一種的閉包的應(yīng)用,只不過其傳遞的是函數(shù):

@makeitalic 裝飾器將函數(shù) hello 傳遞給函數(shù) makeitalic,函數(shù) makeitalic 執(zhí)行完畢后返回被包裝后的 hello 函數(shù),而這個過程其實就是通過閉包實現(xiàn)的。@makebold 也是如此,只不過其傳遞的是 @makeitalic 裝飾過的 hello 函數(shù),因此最后的執(zhí)行結(jié)果 <b> 在 <i> 外層,這個功能如果不用裝飾器,其實就是顯式的使用閉包:

閉包的作用

閉包的最大特點是可以將父函數(shù)的變量與內(nèi)部函數(shù)綁定,并返回綁定變量后的函數(shù)(也即閉包),此時即便生成閉包的環(huán)境(父函數(shù))已經(jīng)釋放,閉包仍然存在,這個過程很像類(父函數(shù))生成實例(閉包),不同的是父函數(shù)只在調(diào)用時執(zhí)行,執(zhí)行完畢后其環(huán)境就會釋放,而類則在文件執(zhí)行時創(chuàng)建,一般程序執(zhí)行完畢后作用域才釋放,因此對一些需要重用的功能且不足以定義為類的行為,使用閉包會比使用類占用更少的資源,且更輕巧靈活,現(xiàn)舉一例:假設(shè)我們僅僅想打印出各類動物的叫聲,分別以類和閉包來實現(xiàn):

可以看到輸出結(jié)果是完全一樣的,但顯然類的實現(xiàn)相對繁瑣,且這里只是想輸出一下動物的叫聲,定義一個 Animal 類未免小題大做,而且 voice 函數(shù)在執(zhí)行完畢后,其作用域就已經(jīng)釋放,但 Animal 類及其實例 dog 的相應(yīng)屬性卻一直貯存在內(nèi)存中:

而這種占用對于實現(xiàn)該功能后,則是沒有必要的。

除此之外,閉包還有很多其他功能,比如用于封裝等,另外,閉包有效的減少了函數(shù)參數(shù)的數(shù)目,這對并行計算非常有價值,比如可以讓每臺電腦負責(zé)一個函數(shù),然后串起來,實現(xiàn)流水化的作業(yè)等。

相關(guān)文章

  • 基于Python實現(xiàn)炸彈人小游戲

    基于Python實現(xiàn)炸彈人小游戲

    這篇文章主要介紹了基于Python中的Pygame模塊實現(xiàn)的炸彈人小游戲,文中的示例代碼講解詳細,對學(xué)習(xí)Python有一定的幫助,感興趣的小伙伴可以學(xué)習(xí)一下
    2021-12-12
  • Python中條件語句、循環(huán)語句和pass語句的使用示例

    Python中條件語句、循環(huán)語句和pass語句的使用示例

    Python條件語句是通過一條或多條語句的執(zhí)行結(jié)果(True或者False)來決定執(zhí)行的代碼塊,下面這篇文章主要給大家介紹了關(guān)于Python中條件語句、循環(huán)語句和pass語句使用的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • PyTorch中torch.manual_seed()的用法實例詳解

    PyTorch中torch.manual_seed()的用法實例詳解

    在Pytorch中可以通過相關(guān)隨機數(shù)來生成張量,并且可以指定生成隨機數(shù)的分布函數(shù)等,下面這篇文章主要給大家介紹了關(guān)于PyTorch中torch.manual_seed()用法的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Jupyter Notebook讀入csv文件時出錯的解決方案

    Jupyter Notebook讀入csv文件時出錯的解決方案

    這篇文章主要介紹了Jupyter Notebook讀入csv文件時出錯的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • 下載糗事百科的內(nèi)容_python版

    下載糗事百科的內(nèi)容_python版

    代碼是沒問題的,可以正常運行,但是希望做到以下2方面: 1、多線程下載 2、代碼分離度更高,跟面向?qū)ο?
    2008-12-12
  • NDArray 與 numpy.ndarray 互相轉(zhuǎn)換方式

    NDArray 與 numpy.ndarray 互相轉(zhuǎn)換方式

    這篇文章主要介紹了NDArray 與 numpy.ndarray 互相轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Python編程實現(xiàn)從字典中提取子集的方法分析

    Python編程實現(xiàn)從字典中提取子集的方法分析

    這篇文章主要介紹了Python編程實現(xiàn)從字典中提取子集的方法,結(jié)合實例形式對比分析了Python采用字典推導(dǎo)式與序列轉(zhuǎn)換實現(xiàn)字典提取子集的相關(guān)操作技巧與優(yōu)缺點,需要的朋友可以參考下
    2018-02-02
  • python實現(xiàn)socket+threading處理多連接的方法

    python實現(xiàn)socket+threading處理多連接的方法

    今天小編就為大家分享一篇python實現(xiàn)socket+threading處理多連接的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • python dict.get()和dict[''key'']的區(qū)別詳解

    python dict.get()和dict[''key'']的區(qū)別詳解

    下面小編就為大家?guī)硪黄猵ython dict.get()和dict['key']的區(qū)別詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • Python pip install之SSL異常處理操作

    Python pip install之SSL異常處理操作

    這篇文章主要介紹了Python pip install之SSL異常處理操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09

最新評論

玛沁县| 东乌| 新建县| 淳化县| 长治市| 中山市| 章丘市| 邹城市| 宣汉县| 云霄县| 黄梅县| 冕宁县| 寿宁县| 福贡县| 湖州市| 彰化市| 恩平市| 隆回县| 海原县| 莒南县| 揭西县| 册亨县| 马龙县| 湘潭县| 黄龙县| 扶风县| 图片| 湖口县| 霍州市| 边坝县| 嵩明县| 金山区| 石景山区| 奈曼旗| 梁河县| 兴山县| 临清市| 万山特区| 依兰县| 泾阳县| 嘉义县|