亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python中decorator使用實(shí)例

 更新時間:2015年04月14日 08:48:06   投稿:junjie  
這篇文章主要介紹了Python中decorator使用實(shí)例,本文講解了如何調(diào)用decorator、decorator函數(shù)的定義、decorator的應(yīng)用場景等內(nèi)容,需要的朋友可以參考下

在我以前介紹 Python 2.4 特性的Blog中已經(jīng)介紹過了decorator了,不過,那時是照貓畫虎,現(xiàn)在再仔細(xì)描述一下它的使用。

關(guān)于decorator的詳細(xì)介紹在 Python 2.4中的What's new中已經(jīng)有介紹,大家可以看一下。

如何調(diào)用decorator

基本上調(diào)用decorator有兩種形式

第一種:

復(fù)制代碼 代碼如下:

@A
def f ():

這種形式是decorator不帶參數(shù)的寫法。最終 Python 會處理為:

復(fù)制代碼 代碼如下:

f = A(f)

還可以擴(kuò)展成:
復(fù)制代碼 代碼如下:

@A
@B
@C
def f ():
   

最終 Python 會處理為:

復(fù)制代碼 代碼如下:

f = A(B(C(f)))

注:文檔上寫的是@A @B @C的形式,但實(shí)際上是不行的,要寫成多行。而且執(zhí)行順序是按函數(shù)調(diào)用順序來的,先最下面的C,然后是B,然后是A。因此,如果decorator有順序話,一定要注意:先要執(zhí)行的放在最下面,最后執(zhí)行的放在最上面。(應(yīng)該不存在這種倒序的關(guān)系)

第二種:

復(fù)制代碼 代碼如下:

@A(args)
def f ():
   

這種形式是decorator帶參數(shù)的寫法。那么 Python 會處理為:

復(fù)制代碼 代碼如下:

def f():
_deco = A(args)
f = _deco(f)

可以看出, Python 會先執(zhí)行A(args)得到一個decorator函數(shù),然后再按與第一種一樣的方式進(jìn)行處理。

decorator函數(shù)的定義

每一個decorator都對應(yīng)有相應(yīng)的函數(shù),它要對后面的函數(shù)進(jìn)行處理,要么返回原來的函數(shù)對象,要么返回一個新的函數(shù)對象。請注意,decorator只用來處理函數(shù)和類方法。

第一種:
針對于第一種調(diào)用形式

復(fù)制代碼 代碼如下:

def A(func):
    #處理func
    #如func.attr='decorated'
    return func
@A
def f(args):pass

上面是對func處理后,仍返回原函數(shù)對象。這個decorator函數(shù)的參數(shù)為要處理的函數(shù)。如果要返回一個新的函數(shù),可以為:

復(fù)制代碼 代碼如下:

def A(func):
    def new_func(args):
        #做一些額外的工作
        return func(args) #調(diào)用原函數(shù)繼續(xù)進(jìn)行處理
    return new_func
@A
def f(args):pass

要注意 new_func的定義形式要與待處理的函數(shù)相同,因此還可以寫得通用一些,如:

復(fù)制代碼 代碼如下:

def A(func):
    def new_func(*args, **argkw):
        #做一些額外的工作
        return func(*args, **argkw) #調(diào)用原函數(shù)繼續(xù)進(jìn)行處理
    return new_func
@A
def f(args):pass

可以看出,在A中定義了新的函數(shù),然后A返回這個新的函數(shù)。在新函數(shù)中,先處理一些事情,比如對參數(shù)進(jìn)行檢查,或做一些其它的工作,然后再調(diào)原始的函數(shù)進(jìn)行處理。這種模式可以看成,在調(diào)用函數(shù)前,通過使用decorator技術(shù),可以在調(diào)用函數(shù)之前進(jìn)行了一些處理。如果你想在調(diào)用函數(shù)之后進(jìn)行一些處理,或者再進(jìn)一步,在調(diào)用函數(shù)之后,根據(jù)函數(shù)的返回值進(jìn)行一些處理可以寫成這樣:

復(fù)制代碼 代碼如下:

def A(func):
    def new_func(*args, **argkw):
        result = func(*args, **argkw) #調(diào)用原函數(shù)繼續(xù)進(jìn)行處理
        if result:
            #做一些額外的工作
            return new_result
        else:
            return result
    return new_func
@A
def f(args):pass

第二種:
針對第二種調(diào)用形式

在文檔上說,如果你的decorator在調(diào)用時使用了參數(shù),那么你的decorator函數(shù)只會使用這些參數(shù)進(jìn)行調(diào)用,因此你需要返回一個新的decorator函數(shù),這樣就與第一種形式一致了。

復(fù)制代碼 代碼如下:

def A(arg):
    def _A(func):
        def new_func(args):
            #做一些額外的工作
            return func(args)
        return new_func
    return _A
@A(arg)
def f(args):pass

可以看出A(arg)返回了一個新的 decorator _A。

decorator的應(yīng)用場景

不過我也一直在想,到底decorator的魔力是什么?適合在哪些場合呢?是否我需要使用它呢?

decorator的魔力就是它可以對所修飾的函數(shù)進(jìn)行加工。那么這種加工是在不改變原來函數(shù)代碼的情況下進(jìn)行的。有點(diǎn)象我知道那么一點(diǎn)點(diǎn)的AOP(面向方面編程)的想法。

它適合的場合我能想到的列舉出下:

1.象文檔中所說,最初是為了使調(diào)用staticmethod和classmethod這樣的方法更方便
2.在某些函數(shù)執(zhí)行前做一些工作,如web開發(fā)中,許多函數(shù)在調(diào)用前需要先檢查一下用戶是否已經(jīng)登錄,然后才能調(diào)用
3.在某此函數(shù)執(zhí)行后做一些工作,如調(diào)用完畢后,根據(jù)返回狀態(tài)寫日志
4.做參數(shù)檢查

可能還有許多,你可以自由發(fā)揮想象

那么我需要用它嗎?

我想那要看你了。不過,我想在某些情況下,使用decorator可以增加程序的靈活性,減少耦合度。比如前面所說的用戶登錄檢查。的確可以寫一個通用的登錄檢查函數(shù),然后在每個函數(shù)中進(jìn)行調(diào)用。但這樣會造成函數(shù)不夠靈活,而且增加了與其它函數(shù)之間的結(jié)合程度。如果用戶登錄檢查功能有所修改,比如返回值的判斷發(fā)生了變化,有可能每個用到它的函數(shù)都要修改。而使用decorator不會造成這一問題。同時使用decorator的語法也使得代碼簡單,清晰(一但你熟悉它的語法的話)。當(dāng)然你不使用它是可以的。不過,這種函數(shù)之間相互結(jié)合的方式,更符合搭積木的要求,它可以把函數(shù)功能進(jìn)一步分解,使得功能足夠簡單和單一。然后再通過decorator的機(jī)制靈活的把相關(guān)的函數(shù)串成一個串,這么一想,還真是不錯。比如下面:

復(fù)制代碼 代碼如下:

@A
@B
def account(args):pass

假設(shè)這是一個記帳處理函數(shù),account只管記帳。但一個真正的記帳還有一些判斷和處理,比如:B檢查帳戶狀態(tài),A記日志。這樣的效果其實(shí)是先檢查B、通過在A中的處理可以先執(zhí)行account,然后再進(jìn)行記日志的處理。象搭積木一樣很方便,改起來也容易。甚至可以把a(bǔ)ccount也寫成decorator,而下面執(zhí)行的函數(shù)是一個空函數(shù)。然后再通過配置文件等方法,將decorator的組合保存起來,就基本實(shí)現(xiàn)功能的組裝化。是不是非常理想。

Python 帶給人的創(chuàng)造力真是無窮啊!

相關(guān)文章

  • python函數(shù)中return后的語句一定不會執(zhí)行嗎?

    python函數(shù)中return后的語句一定不會執(zhí)行嗎?

    這篇文章主要給大家詳細(xì)分析講解了關(guān)于python函數(shù)中return語句后的語句是否一定不會執(zhí)行的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-07-07
  • 使用豆瓣提供的國內(nèi)pypi源

    使用豆瓣提供的國內(nèi)pypi源

    PyPI(Python Package Index)是python官方的第三方庫的倉庫,所有人都可以下載第三方庫或上傳自己開發(fā)的庫到PyPI。PyPI推薦使用pip包管理器來下載第三方庫。
    2017-07-07
  • Python3中省略號(...)用法介紹

    Python3中省略號(...)用法介紹

    本文主要介紹了Python3中省略號(...)用法介紹,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 基于python生成詞云圖的代碼示例

    基于python生成詞云圖的代碼示例

    這篇文章主要個介紹了如何基于python生成詞云圖的代碼示例,文中有詳細(xì)的代碼示例喝圖文講解,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-11-11
  • 詳解Python二維數(shù)組與三維數(shù)組切片的方法

    詳解Python二維數(shù)組與三維數(shù)組切片的方法

    這篇文章主要介紹了詳解Python二維數(shù)組與三維數(shù)組切片的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • python中json格式數(shù)據(jù)輸出的簡單實(shí)現(xiàn)方法

    python中json格式數(shù)據(jù)輸出的簡單實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄猵ython中json格式數(shù)據(jù)輸出的簡單實(shí)現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • linux平臺使用Python制作BT種子并獲取BT種子信息的方法

    linux平臺使用Python制作BT種子并獲取BT種子信息的方法

    這篇文章主要介紹了linux平臺使用Python制作BT種子并獲取BT種子信息的方法,結(jié)合實(shí)例形式詳細(xì)分析了Python BT模塊的安裝及針對BT種子文件的相關(guān)操作技巧,需要的朋友可以參考下
    2017-01-01
  • Django自定義排序ORM示例詳解

    Django自定義排序ORM示例詳解

    這篇文章主要為大家介紹了Django自定義排序ORM示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • python自動化測試通過日志3分鐘定位bug

    python自動化測試通過日志3分鐘定位bug

    軟件開發(fā)中通過日志記錄程序的運(yùn)行情況是一個開發(fā)的好習(xí)慣,對于錯誤排查和系統(tǒng)運(yùn)維都有很大幫助,Python標(biāo)準(zhǔn)庫自帶了強(qiáng)大的logging日志模塊,在各種python模塊中得到廣泛應(yīng)用
    2021-11-11
  • python中validators庫的使用方法詳解

    python中validators庫的使用方法詳解

    這篇文章主要介紹了python中validators庫的使用方法詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09

最新評論