成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Python中的函數(shù)裝飾器和閉包

caozhijian / 643人閱讀

摘要:變量查找規(guī)則在中一個變量的查找順序是局部環(huán)境,閉包,全局,內(nèi)建閉包引用了自由變量的函數(shù)。閉包的作用閉包的最大特點是可以將父函數(shù)的變量與內(nèi)部函數(shù)綁定,并返回綁定變量后的函數(shù),此時即便生成閉包的環(huán)境父函數(shù)已經(jīng)釋放,閉包仍然存在。

導(dǎo)語:本文章記錄了本人在學(xué)習(xí)Python基礎(chǔ)之函數(shù)篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學(xué)習(xí)并交流。

本文重點:

1、掌握裝飾器的本質(zhì)、功能和特點;
2、了解閉包的概念以及Python變量調(diào)用規(guī)則;
3、了解并學(xué)會使用標準庫中重要的裝飾器;
4、掌握參數(shù)化裝飾器的意義和代碼實現(xiàn)方式。
一、裝飾器基礎(chǔ)知識

裝飾器功能(decorator):將被裝飾的函數(shù)當作參數(shù)傳遞給與裝飾器對應(yīng)的函數(shù)(名稱相同的函數(shù)),并返回包裝后的被裝飾的函數(shù)。
裝飾器本質(zhì):是一個返回函數(shù)的高階函數(shù)。
裝飾器特點:

1、多數(shù)裝飾器會把被裝飾的函數(shù)替換成其他函數(shù)
2、函數(shù)裝飾器在導(dǎo)入模塊時立即執(zhí)行,而被裝飾的函數(shù)只在明確調(diào)用時執(zhí)行。

裝飾器有時采用嵌套函數(shù)表示的原因(個人理解):
一些裝飾器的裝飾功能只有在被裝飾函數(shù)被調(diào)用時方可觸發(fā),因此需要用嵌套函數(shù)的形式來編寫。

二、自由變量、閉包與nonlocal聲明

自由變量(free variable):指未在本地作用域綁定的變量,介于局部變量和全局變量之間。
變量查找規(guī)則:在python中, 一個變量的查找順序是 LEGB (L:Local 局部環(huán)境,E:Enclosing 閉包,G:Global 全局,B:Built-in 內(nèi)建).

閉包:引用了自由變量的函數(shù)。

閉包的作用:

閉包的最大特點是可以將父函數(shù)的變量與內(nèi)部函數(shù)綁定,并返回綁定變量后的函數(shù),此時即便生成閉包的環(huán)境(父函數(shù))已經(jīng)釋放,閉包仍然存在。

這個過程很像類(父函數(shù))生成實例(閉包),不同的是父函數(shù)只在調(diào)用時執(zhí)行,執(zhí)行完畢后其環(huán)境就會釋放,而類則在文件執(zhí)行時創(chuàng)建,一般程序執(zhí)行完畢后作用域才釋放。

因此對一些需要重用的功能且不足以定義為類的行為,使用閉包會比使用類占用更少的資源,且更輕巧靈活。

nonlocal聲明:可以將局部變量聲明為自由變量。

eg:計算移動平均值的高階函數(shù):

def averager():
    sum=0
    n=0
    def avg(i):
        nonlocal sum,n
        sum+=i
        n+=1
        return print(sum/n)
    return avg  
a=averager()
a(3)
a(5)
a(7)

輸出分別是3,4,5

三、裝飾器進階使用 1.標準庫中的裝飾器

Python內(nèi)置了三個用于裝飾方法的函數(shù):property,classmethod和staticmethod
三個重要的內(nèi)置裝飾器:

functools.wraps:
(1)協(xié)助構(gòu)建行為良好的裝飾器。
(2)可以把被裝飾對象的相關(guān)屬性復(fù)制到裝飾器中,默認有 __module__、__name__、__doc__。
(3)個人理解,裝飾器在實現(xiàn)裝飾的過程中意見把被裝飾函數(shù)替換了。此時你想調(diào)用被裝飾函數(shù)的__doc__和__name__會發(fā)現(xiàn)是none,此時通過functools.wraps就可以在裝飾時把相關(guān)屬性復(fù)制過來使用,避免這個問題發(fā)生。

functools.lru_cache
(1)實現(xiàn)備忘功能,即緩存,避免發(fā)生重復(fù)調(diào)用來提高效率。
(2)注意調(diào)用時必須帶括號,因為此裝飾器包含maxsize和typed兩個參數(shù),帶括號表示使用默認參數(shù)。否則 functools.lru_cache不清楚該如何執(zhí)行。

functools.singledispatch
為函數(shù)提供重載功能。被其裝飾的函數(shù)會成為泛函數(shù)(generic function):根據(jù)第一個參數(shù)的類型,用不同的方式執(zhí)行相同操作的一組函數(shù)。

以functools.lru_cache為例實現(xiàn)斐波那契函數(shù)的計時裝飾器:.

import time
import functools
def clock(func):
    @functools.lru_cache()#減少重復(fù)自引用,避免重復(fù)計算
    def clocked(arg):
        t0=time.perf_counter()
        func(arg)
        result=func(arg)
        t1=time.perf_counter()
        processtime=t1-t0
        name=func.__name__
        print("[{0:.8f}] {1}({2})={3}".format(processtime,name,arg,result))
        return result#非常重要,否則破壞原fibs函數(shù)導(dǎo)致無法遞歸調(diào)用。
    return clocked
 
@clock
def fibs(n):
    if n<2:
        return 1
    else:
        return fibs(n-1)+fibs(n-2)
fibs(6)#輸出8
2.疊放裝飾器

如同函數(shù)可以嵌套使用,裝飾器亦可以疊放起來裝飾同一對象。語法如下:
@d1
@d2
def f1():
pass
上述裝飾操作等價于d1(d2(f)),故易知疊放在上端的裝飾器靠后執(zhí)行。

3.參數(shù)化裝飾器

普通裝飾器的進階版,通過參數(shù)接口可以更方便的定制我們需要的裝飾器,適應(yīng)需求變化。
代碼實現(xiàn)較普通裝飾器多嵌套一層函數(shù),用來傳遞用戶輸入的參數(shù)。以計時器舉例形式如下:

import time
DEFAULT_FMT = "[{elapsed:0.8f}s] {name}({args}) -> {result}"
def clock(fmt=DEFAULT_FMT): #三層函數(shù)來實現(xiàn)
    def decorate(func): 
        def clocked(*_args): 
            t0 = time.time()
            _result = func(*_args) 
            elapsed = time.time() - t0
            name = func.__name__
            args = ", ".join(repr(arg) for arg in _args) 
            result = repr(_result) 
            print(fmt.format(**locals())) 
            return _result 
        return clocked 
    return decorate 
if __name__ == "__main__":
    @clock()
    def snooze(seconds):
        time.sleep(seconds)
    for i in range(3):
        snooze(.123)

輸出:

[0.12480044s] snooze(0.123) -> None
[0.13660240s] snooze(0.123) -> None
[0.12480044s] snooze(0.123) -> None
4.類裝飾器

上邊實現(xiàn)參數(shù)化裝飾器的代碼由于包含三重嵌套略顯復(fù)雜, 事實上復(fù)雜的裝飾器用 class 實現(xiàn)更方便。通過 __call__ 方法即可改寫參數(shù)化裝飾器。具體實現(xiàn)留作勤勞的你去課后思考,感興趣的可以與我私信交流。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/41475.html

相關(guān)文章

  • Python學(xué)習(xí)之路26-函數(shù)裝飾器和閉包

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

    sunny5541 評論0 收藏0
  • 流暢的python讀書筆記-第七章-函數(shù)裝飾器和閉包

    摘要:函數(shù)裝飾器和閉包嚴格來說,裝飾器只是語法糖。何時執(zhí)行裝飾器它們在被裝飾的函數(shù)定義之后立即運行。裝飾器突出了被裝飾的函數(shù)的作用,還便于臨時禁用某個促銷策略只需把裝飾器注釋掉。 函數(shù)裝飾器和閉包 嚴格來說,裝飾器只是語法糖。如前所示,裝飾器可以像常規(guī)的可調(diào)用對象那樣調(diào)用,其參數(shù)是另一個函數(shù)。有時,這樣做更方便,尤其是做元編程(在運行時改變程序的行為)時。 Python何時執(zhí)行裝飾器 它們在...

    Hydrogen 評論0 收藏0
  • Python_裝飾器和生成器

    摘要:迭代器迭代是訪問集合元素的一種方式。迭代器是一個可以記住遍歷的位置的對象,迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結(jié)束,迭代器只往前不會往后退。生成器特點保存了一套生成數(shù)值的算法。 迭代器 迭代是訪問集合元素的一種方式。迭代器是一個可以記住遍歷的位置的對象,迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結(jié)束,迭代器只往前不會往后退。 可迭代對象 以直接...

    sugarmo 評論0 收藏0
  • Python 函數(shù)式編程、裝飾器以及一些相關(guān)概念簡介

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

    Jinkey 評論0 收藏0

發(fā)表評論

0條評論

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