国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python 的閉包和裝飾器

justCoding / 1598人閱讀

摘要:所以,有另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。

對于已經對 閉包 或者 裝飾器有一定概念的,可以直接通過右側標題目錄直接定位到相應段落查看所需的內容。

什么是裝飾器?

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

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

栗子:

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

解析過程是這樣子的:
1.python 解釋器發現@dobi,就去調用與其對應的函數( dobi 函數)
2.dobi 函數調用前要指定一個參數,傳入的就是@dobi下面修飾的函數,也就是 qinfeng()
3.dobi() 函數執行,調用 qinfeng(),qinfeng() 打印“dobi”

什么是閉包?

首先還得從基本概念說起,什么是閉包呢?來看下維基上的解釋:
在計算機科學中,閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即使已經離開了創造它的環境也不例外。所以,有另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。閉包在運行時可以有多個實例,不同的引用環境和相同的函數組合可以產生不同的實例。
....
上面提到了兩個關鍵的地方: 自由變量 和 函數, 這兩個關鍵稍后再說。還是得在贅述下“閉包”的意思,望文知意,可以形象的把它理解為一個封閉的包裹,這個包裹就是一個函數,當然還有函數內部對應的邏輯,包裹里面的東西就是自由變量,自由變量可以在隨著包裹到處游蕩。當然還得有個前提,這個包裹是被創建出來的。
在通過Python的語言介紹一下,一個閉包就是你調用了一個函數A,這個函數A返回了一個函數B給你。這個返回的函數B就叫做閉包。你在調用函數A的時候傳遞的參數就是自由變量。
舉個栗子:

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

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

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

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

nonlocal 語句

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

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

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

閉包與裝飾器

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

@makeitalic 裝飾器將函數 hello 傳遞給函數 makeitalic,函數 makeitalic 執行完畢后返回被包裝后的 hello 函數,而這個過程其實就是通過閉包實現的。@makebold 也是如此,只不過其傳遞的是 @makeitalic 裝飾過的 hello 函數,因此最后的執行結果 外層,這個功能如果不用裝飾器,其實就是顯式的使用閉包:

閉包的作用

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

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

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

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

參考資料

1、python 深入閉包
2、python 中的閉包
3、什么是閉包

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/37775.html

相關文章

  • Python函數裝飾閉包

    摘要:變量查找規則在中一個變量的查找順序是局部環境,閉包,全局,內建閉包引用了自由變量的函數。閉包的作用閉包的最大特點是可以將父函數的變量與內部函數綁定,并返回綁定變量后的函數,此時即便生成閉包的環境父函數已經釋放,閉包仍然存在。 導語:本文章記錄了本人在學習Python基礎之函數篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。 本文重點: 1、掌握裝飾器的本質、功...

    caozhijian 評論0 收藏0
  • Python學習之路26-函數裝飾閉包

    摘要:初步認識裝飾器函數裝飾器用于在源代碼中標記函數,以某種方式增強函數的行為。函數裝飾器在導入模塊時立即執行,而被裝飾的函數只在明確調用時運行。只有涉及嵌套函數時才有閉包問題。如果想保留函數原本的屬性,可以使用標準庫中的裝飾器。 《流暢的Python》筆記本篇將從最簡單的裝飾器開始,逐漸深入到閉包的概念,然后實現參數化裝飾器,最后介紹標準庫中常用的裝飾器。 1. 初步認識裝飾器 函數裝飾...

    sunny5541 評論0 收藏0
  • Python 函數式編程、裝飾以及一些相關概念簡介

    摘要:重寫內建名字空間中的函數閉包閉包是詞法閉包的簡稱。另一種說法認為閉包是由函數和與其相關的引用環境組合而成的實體。 Python 中的 Decorator(裝飾器) 是對一個函數或者方法的封裝,從而使其可以完成一些與自身功能無關的工作。 預備知識 一切皆對象 在 Python 中,所有的一切都被視為對象,任何的變量、函數、類等都是 object 的子類。因此除了變量之外,函數和類等也可以...

    Jinkey 評論0 收藏0
  • 流暢 Python - 5. 裝飾閉包

    摘要:看了這一章,發現原來是裝飾器,又一新知識。期間,裝飾器會做一些額外的工作。書中介紹了模塊中的三個裝飾器。另一個是,這個裝飾器把函數結果保存了起來,避免傳入相同參數時重復計算。疊放不奇怪,裝飾器返回的就是函數或可調用對象。 在 Web 框架 Flask 中,最??吹降幕蛟S是以@app.route開頭的那行代碼。由于還是剛接觸 Flask,所以對這種語法還不熟悉??戳诉@一章,發現原來是裝飾...

    Markxu 評論0 收藏0
  • 說說Python閉包 - Closure

    摘要:閉包可以用來在一個函數與一組私有變量之間創建關聯關系。夾帶私貨外部變量返回的是函數,帶私貨的函數支持將函數當成對象使用的編程語言,一般都支持閉包。所以說當你的裝飾器需要自定義參數時,一般都會形成閉包。 Python中的閉包不是一個一說就能明白的概念,但是隨著你往學習的深入,無論如何你都需要去了解這么一個東西。 閉包的概念 我們嘗試從概念上去理解一下閉包。 在一些語言中,在函數中可以(嵌...

    leon 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<