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

Python的幾個(gè)高級(jí)語(yǔ)法概念淺析(lambda表達(dá)式閉包裝飾器)

 更新時(shí)間:2016年05月28日 12:44:44   投稿:mdxy-dxy  
本文主要記錄自己對(duì)幾個(gè)高級(jí)語(yǔ)法概念的理解:匿名函數(shù)、lambda表達(dá)式、閉包、裝飾器。這幾個(gè)概念并非Python特有,但本文只限于用Python做說(shuō)明

1. 匿名函數(shù)
匿名函數(shù)(anonymous function)是指未與任何標(biāo)識(shí)符綁定的函數(shù),多用在functional programming languages領(lǐng)域,典型應(yīng)用場(chǎng)合:
1) 作為參數(shù)傳給高階函數(shù)(higher-order function ),如python中的built-in函數(shù)filter/map/reduce都是典型的高階函數(shù)
2) 作為高階函數(shù)的返回值(雖然此處的"值"實(shí)際上是個(gè)函數(shù)對(duì)象)
與命名函數(shù)(named function)相比,若函數(shù)只被調(diào)用1次或有限次,則匿名函數(shù)在語(yǔ)法上更輕量級(jí)。
具體語(yǔ)法上,python通過(guò)lambda語(yǔ)法支持函數(shù)體為表達(dá)式的匿名函數(shù),即:python的lambda表達(dá)式本質(zhì)上是個(gè)匿名函數(shù),但其函數(shù)體只能是個(gè)表達(dá)式,不能包含其它語(yǔ)句。
此外,高級(jí)動(dòng)態(tài)語(yǔ)言常借助匿名函數(shù)實(shí)現(xiàn)閉包(closure)或裝飾器(decorator)等高級(jí)語(yǔ)法。
在一些場(chǎng)合下,lambda表達(dá)式的使用使得python程序看起來(lái)非常簡(jiǎn)潔。例如,下面是根據(jù)value對(duì)dict元素做排序的代碼示例:

>>> foo = {'father' : 65, 'mother' : 62, 'sister' : 38, 'brother' : 29, 'me' : 28}
>>> sorted(foo.iteritems(), key=lambda x: x[1])
[('me', 28), ('brother', 29), ('sister', 38), ('mother', 62), ('father', 65)]

2. 閉包
閉包(closure)本質(zhì)上是一個(gè)包含了其引用環(huán)境(referencing environment)的函數(shù)或函數(shù)引用,這里的"引用環(huán)境"通常由一張表來(lái)維護(hù),該表存儲(chǔ)了函數(shù)體會(huì)訪問(wèn)的非局部變量(non-local variables)的引用。
與C語(yǔ)言中的函數(shù)指針相比,閉包允許嵌套函數(shù)訪問(wèn)其作用域外的non-local變量,這與Python解釋器對(duì)變量的作用域查找規(guī)則有關(guān)(Python支持LEGB的查找規(guī)則,想深究的話,可以參考<Learning Python>第4版第17章Scopes關(guān)于作用域及查找規(guī)則的詳細(xì)講解,或者查看這篇文章 做快速了解)。
對(duì)于運(yùn)行時(shí)內(nèi)存分配模型會(huì)在線性棧上創(chuàng)建局部變量的語(yǔ)言來(lái)說(shuō)(典型如C語(yǔ)言),通常很難支持閉包。因?yàn)檫@些語(yǔ)言底層實(shí)現(xiàn)中,若函數(shù)返回,則函數(shù)中定義的局部變量均會(huì)隨著函數(shù)棧被回收而銷(xiāo)毀。但閉包在底層實(shí)現(xiàn)上要求其要訪問(wèn)的non-local變量在閉包被執(zhí)行的時(shí)候保持有效,直到這個(gè)閉包的生命周期結(jié)束,這意外著這些non-local變量只有在其確定不再被使用時(shí)才能銷(xiāo)毀,而不能隨著定義這些變量的函數(shù)返回銷(xiāo)毀。因此,天生支持閉包的語(yǔ)言通常采用garbage collection的方式管理內(nèi)存,因?yàn)間c機(jī)制保證了變量只有不再被引用時(shí)才會(huì)由系統(tǒng)銷(xiāo)毀并回收其內(nèi)存空間。
具體語(yǔ)法上,閉包通常伴隨著函數(shù)嵌套定義。以Python為例,一個(gè)簡(jiǎn)單的閉包示例如下:

#!/bin/env python
#-*- encoding: utf-8 -*-

def startAt_v1(x):
 def incrementBy(y):
  return x + y 
 print 'id(incrementBy)=%s' % (id(incrementBy))
 return incrementBy

def startAt_v2(x):
 return lambda y: x + y 

if '__main__' == __name__:
 c1 = startAt_v1(2)
 print 'type(c1)=%s, c1(3)=%s' % (type(c1), c1(3))
 print 'id(c1)=%s' % (id(c1))
 
 c2 = startAt_v2(2)
 print 'type(c2)=%s, c2(3)=%s' % (type(c2), c2(3))

執(zhí)行結(jié)果如下:

id(incrementBy)=139730510519782
type(c1)=<type 'function'>, c1(3)=5
id(c1)=139730510519782
type(c2)=<type 'function'>, c2(3)=5

上述示例中,startAt_v1和startAt_v2均實(shí)現(xiàn)了閉包,其中:v1借助嵌套定義函數(shù)實(shí)現(xiàn);v2則借助lambda表達(dá)式/匿名函數(shù)來(lái)實(shí)現(xiàn)。
我們以v1為例對(duì)閉包做說(shuō)明:
1) 函數(shù)startAt_v1接受1個(gè)參數(shù),返回1個(gè)函數(shù)對(duì)象,而這個(gè)函數(shù)對(duì)象的行為由嵌套定義的函數(shù)incrementBy實(shí)現(xiàn)。
2) 對(duì)函數(shù)incrementBy來(lái)說(shuō),變量x就是所謂的non-local變量(因?yàn)閤既非該函數(shù)定義的局部變量,又非普通意義上的全局變量),incrementBy實(shí)現(xiàn)具體的函數(shù)行為并返回。
3) main入口的c1接收到的返回值是個(gè)函數(shù)對(duì)象,從id(incrementBy) == id(c1)可斷定,c1"指向"的對(duì)象與函數(shù)名incrementBy"指向"的其實(shí)是同一個(gè)函數(shù)對(duì)象。
4) 受益于Python對(duì)閉包的支持,與普通函數(shù)的對(duì)象相比,c1指向的對(duì)象可以訪問(wèn)不在其函數(shù)作用域內(nèi)的non-local變量,而這個(gè)變量是由incrementBy的外層包裝函數(shù)startAt_v1的入?yún)⑻峁┑?,于是,相?dāng)于c1指向的函數(shù)對(duì)象對(duì)其外層包裝函數(shù)的入?yún)⒕哂?記憶"功能,通過(guò)調(diào)用外層包裝函數(shù)創(chuàng)建閉包時(shí),不同的入?yún)⒈粌?nèi)層函數(shù)作為引用環(huán)境維護(hù)起來(lái)。
5) 調(diào)用c1(3)時(shí),傳入的參數(shù)與引用環(huán)境維護(hù)的外層包裝函數(shù)的參數(shù)一起運(yùn)算得到最終結(jié)果。
以上步驟分析說(shuō)明了一個(gè)閉包從創(chuàng)建到執(zhí)行的基本原理,理解這個(gè)case后,閉包的概念也應(yīng)該清晰了。

3. 裝飾器
python支持裝飾器(decorator)語(yǔ)法。裝飾器的概念對(duì)于初學(xué)者來(lái)說(shuō)比較晦澀,因?yàn)樗婕暗胶瘮?shù)式編程的幾個(gè)概念(如匿名函數(shù)、閉包),這也是本文先介紹匿名函數(shù)和閉包的原因。

我們引用這篇文章對(duì)裝飾器的定義:
A decorator is a function that takes a function object as an argument, and returns a function object as a return value.
從這個(gè)定義可知,裝飾器本質(zhì)上只是一個(gè)函數(shù),它借助閉包的語(yǔ)法去修改一個(gè)函數(shù)(又稱被裝飾函數(shù))的行為,即decorator其實(shí)是個(gè)閉包函數(shù),該函數(shù)以被裝飾函數(shù)名(這個(gè)函數(shù)名其實(shí)是一個(gè)函數(shù)對(duì)象的引用)作為入?yún)?,在閉包內(nèi)修改被裝飾函數(shù)的行為后,返回一個(gè)新的函數(shù)對(duì)象。
特別說(shuō)明:decorator并非必須以函數(shù)形式出現(xiàn),它可以是任何可被調(diào)用的對(duì)象,例如它也可以class形式出現(xiàn),參見(jiàn)這篇文章給出的例子。
在定義好函數(shù)裝飾器的前提下,當(dāng)外部調(diào)用這個(gè)被裝飾函數(shù)時(shí),decorator的語(yǔ)法糖會(huì)由Python解釋器解釋為先執(zhí)行裝飾器函數(shù),然后在裝飾器返回的新函數(shù)對(duì)象上繼續(xù)執(zhí)行其余語(yǔ)句。
來(lái)個(gè)實(shí)例分析一下:

#!/bin/env python
#-*- encoding: utf-8 -*-

def wrapper(fn):
 def inner(n, m):
  n += 1
  print 'in inner: fn=%s, n=%s, m=%s' % (fn.__name__, n, m)
  return fn(n, m) + 6 // 這里有return且返回值為int對(duì)象
 return inner

@wrapper
def foo(n, m):
 print 'in foo: n=%s, m=%s' % (n, m)
 return n * m

print foo(2, 3)

上面的示例中,foo通過(guò)@wrapper語(yǔ)法糖聲明它的裝飾器是wrapper,在wrapper中,定義了嵌套的inner函數(shù)(該函數(shù)的參數(shù)列表必須與被裝飾函數(shù)foo的參數(shù)列表保持一致),裝飾器wrapper修改foo的行為后,返回inner(注意:由于inner的返回值是個(gè)int對(duì)象,故wrpper最終返回的也是個(gè)int對(duì)象)。
調(diào)用foo(2, 3)時(shí),Python解釋器先調(diào)用wrapper對(duì)foo做行為改寫(xiě),然后返回int對(duì)象,不難推測(cè),上述代碼的執(zhí)行結(jié)果如下:

in inner: fn=foo, n=3, m=3
in foo: n=3, m=3
foo(2, 3)=15

相關(guān)文章

  • Python集成學(xué)習(xí)之Blending算法詳解

    Python集成學(xué)習(xí)之Blending算法詳解

    集成學(xué)習(xí)(又稱模型融合)就是結(jié)合若干個(gè)體分類器(基學(xué)習(xí)器)進(jìn)行綜合預(yù)測(cè),各個(gè)個(gè)體學(xué)習(xí)器通常是弱學(xué)習(xí)器.集成學(xué)習(xí)相較于個(gè)體學(xué)習(xí)在預(yù)測(cè)準(zhǔn)確率以及穩(wěn)定性上都有很大的提高.文中有非常詳細(xì)的代碼示例哦,需要的朋友可以參考下
    2021-05-05
  • 詳解Django+Uwsgi+Nginx 實(shí)現(xiàn)生產(chǎn)環(huán)境部署

    詳解Django+Uwsgi+Nginx 實(shí)現(xiàn)生產(chǎn)環(huán)境部署

    這篇文章主要介紹了詳解Django+Uwsgi+Nginx 實(shí)現(xiàn)生產(chǎn)環(huán)境部署,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • python?print無(wú)法打印\r的問(wèn)題及解決

    python?print無(wú)法打印\r的問(wèn)題及解決

    這篇文章主要介紹了python?print無(wú)法打印\r的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • python批量查詢、漢字去重處理CSV文件

    python批量查詢、漢字去重處理CSV文件

    這篇文章主要為大家詳細(xì)介紹了python批量查詢、漢字去重處理CSV文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • 使用sklearn之LabelEncoder將Label標(biāo)準(zhǔn)化的方法

    使用sklearn之LabelEncoder將Label標(biāo)準(zhǔn)化的方法

    今天小編就為大家分享一篇使用sklearn之LabelEncoder將Label標(biāo)準(zhǔn)化的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • python 多線程實(shí)現(xiàn)檢測(cè)服務(wù)器在線情況

    python 多線程實(shí)現(xiàn)檢測(cè)服務(wù)器在線情況

    本文給大家分享的是Python使用多線程通過(guò)ping命令檢測(cè)服務(wù)器的在線狀況,給大家了內(nèi)網(wǎng)和外網(wǎng)的2個(gè)例子,有需要的小伙伴可以參考下。
    2015-11-11
  • Python實(shí)現(xiàn)不規(guī)則圖形填充的思路

    Python實(shí)現(xiàn)不規(guī)則圖形填充的思路

    這篇文章主要介紹了Python實(shí)現(xiàn)不規(guī)則圖形填充的思路,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 解決pytorch 損失函數(shù)中輸入輸出不匹配的問(wèn)題

    解決pytorch 損失函數(shù)中輸入輸出不匹配的問(wèn)題

    這篇文章主要介紹了解決pytorch 損失函數(shù)中輸入輸出不匹配的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 解決python遞歸函數(shù)及遞歸次數(shù)受到限制的問(wèn)題

    解決python遞歸函數(shù)及遞歸次數(shù)受到限制的問(wèn)題

    這篇文章主要介紹了解決python遞歸函數(shù)及遞歸次數(shù)受到限制的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • PyCharm 安裝與使用配置教程(windows,mac通用)

    PyCharm 安裝與使用配置教程(windows,mac通用)

    很多小伙伴下載安裝PyCharm后不會(huì)使用,這篇文章詳細(xì)介紹了PyCharm安裝與使用教程(windows,mac通用),需要的朋友可以參考下
    2021-05-05

最新評(píng)論

靖州| 彰化市| 鸡东县| 陆良县| 固始县| 巢湖市| 策勒县| 永定县| 民和| 伊吾县| 邵阳市| 青河县| 巴东县| 柳林县| 噶尔县| 新巴尔虎右旗| 谷城县| 山西省| 通州区| 封丘县| 乌恰县| 池州市| 兰考县| 平利县| 河北区| 高清| 安阳市| 涪陵区| 玉树县| 广西| 灵石县| 琼结县| 二连浩特市| 孟州市| 龙川县| 安塞县| 屯门区| 大方县| 洛南县| 陆川县| 红桥区|