欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python?Decorator的設(shè)計(jì)模式演繹過程解析

 更新時(shí)間:2022年07月05日 16:24:31   作者:_Zhao  
本文主要梳理了Python?decorator的實(shí)現(xiàn)思路,解釋了為什么Python?decorator是現(xiàn)在這個(gè)樣子,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

關(guān)于代理模式、裝飾模式

設(shè)計(jì)模式中經(jīng)常提到的代理模式、裝飾模式,這兩種叫法實(shí)際上是說的同一件事,只是側(cè)重點(diǎn)有所不同而已。

這兩者都是通過在原有對象的基礎(chǔ)上封裝一層對象,通過調(diào)用封裝后的對象而不是原來的對象來實(shí)現(xiàn)代理/裝飾的目的。

例如:(以Java為例)

public class CountProxy implements Count {
    private CountImpl countImpl;
    public CountProxy(CountImpl countImpl) {
        this.countImpl = countImpl;
    }
    @Override
    public void queryCount() {  
        System.out.println("事務(wù)處理之前");
        // 調(diào)用委托類的方法;
        countImpl.queryCount();
        System.out.println("事務(wù)處理之后");
    }
    @Override
    public void updateCount() {
        System.out.println("事務(wù)處理之前");
        // 調(diào)用委托類的方法;
        countImpl.updateCount();
        System.out.println("事務(wù)處理之后");
    }
}

在這個(gè)例子中CountProxy是對CountImpl的封裝。

使用者通過CountProxy.queryCount方法來調(diào)用CountImpl.queryCount方法,這被稱為代理,即CountProxy是代理類,CountImpl是被代理類。

CountProxy.queryCount方法中,可以在CountImpl.queryCount方法調(diào)用之前和之后添加一些額外的操作,被稱為裝飾,即CountProxy是裝飾類,CountImpl是被裝飾類。

如果強(qiáng)調(diào)通過CountProxy 對CountImpl進(jìn)行代理的作用,則稱為代理模式;

如果強(qiáng)調(diào)通過CountProxy 對CountImpl增加額外的操作,則稱為裝飾模式;

不論是哪種稱呼,其本質(zhì)都在于對原有對象的封裝。

其封裝的目的在于增強(qiáng)所封裝對象的功能或管理所封裝的對象。

從上面的例子也可以發(fā)現(xiàn),代理/封裝所圍繞的核心是可調(diào)用對象(比如函數(shù))。

Python中的代理/裝飾

Python中的可調(diào)用對象包括函數(shù)、方法、實(shí)現(xiàn)了__call__方法的類。

Python中的函數(shù)也是對象,可以作為高階函數(shù)的參數(shù)傳入或返回值返回。

因此,當(dāng)代理/裝飾的對象是函數(shù)時(shí),可以使用高階函數(shù)來對某個(gè)函數(shù)進(jìn)行封裝。

例如:

def query_count_proxy(fun, name, age):
    print('do something before')
    rv = fun(name, age)
    print('do something after')
    return rv
def query_count(name, age):
    print('name is %s, age is %d' % (name, age))
query_count_proxy(query_count, 'Lee', 20)

但是,這個(gè)例子中,query_count函數(shù)作為參數(shù)傳入query_count_proxy函數(shù)中,并在query_count_proxy函數(shù)中被調(diào)用,其結(jié)果作為返回值返回。這就完成了代理的功能,同時(shí),在調(diào)用query_count函數(shù)的前后,我們還增加了裝飾代碼。

但是,query_count_proxy的函數(shù)參數(shù)與query_count不一樣了,理想的代理應(yīng)該保持接口一致才對。

為了保持一致,我們可以利用高階函數(shù)可以返回函數(shù)的特點(diǎn)來完成:

def query_count_proxy(fun):
    def wrapper(name, age):
        print('do something before')
        rv = fun(name, age)
        print('do something after')
        return rv
    return wrapper
def query_count(name, age):
    print('name is %s, age is %d' % (name, age))
query_count_proxy(query_count)('Lee', 20)

修改后的例子,query_count_proxy僅負(fù)責(zé)接受被代理的函數(shù)query_count作為參數(shù),同時(shí),返回一個(gè)函數(shù)對象wrapper作為返回值,真正的封裝動(dòng)作在wrapper這個(gè)函數(shù)中完成。

此時(shí),如果調(diào)用query_count_proxy(query_count)就得到了wrapper函數(shù)對象,則,執(zhí)行query_count_proxy(query_count)('Lee', 20)就相當(dāng)于執(zhí)行了wrapper('Lee', 20)

但是可以看到,query_count_proxy(query_count)('Lee', 20)這種使用方法,仍然不能保證一致。

為了保持一致,我們需要利用Python中對象與其名稱可以動(dòng)態(tài)綁定的特點(diǎn)。不使用query_count_proxy(quer_count)('Lee', 20)來調(diào)用代理函數(shù),而是使用下面兩句:

query_count = query_count_proxy(query_count)
query_count('Lee', 20)

執(zhí)行query_count_proxy(query_count)生成wrapper函數(shù)對象,將這個(gè)對象通過query_count = query_count_proxy(query_count)綁定到query_count這個(gè)名字上來,這樣執(zhí)行query_count('Lee', 20)時(shí),其實(shí)執(zhí)行的是wrapper('Lee', 20)

這么做的結(jié)果就是:使用代理時(shí)調(diào)用query_count('Lee', 20)與不使用代理時(shí)調(diào)用query_count('Lee', 20)對使用者而言保持不變,不用改變代碼,但是在真正執(zhí)行時(shí),使用的是代理/裝飾后的函數(shù)。

這里,基本利用Python的高階函數(shù)及名稱綁定完成了代理/裝飾的功能。

還有什么不理想的地方呢?

對,就是query_count = query_count_proxy(query_count),因?yàn)檫@句既不簡潔,又屬于重復(fù)工作。

Python為我們提供了語法糖來完成這類的tedious work。

方法就是:

@query_count_proxy
def query_count(name, age):
    return 'name is %s, age is %d' % (name, age)

query_count = query_count_proxy(query_count)就等同于在定義query_count函數(shù)的時(shí)候,在其前面加上@query_count_proxy。

Python看到這樣的語法,就會(huì)自動(dòng)的執(zhí)行query_count = query_count_proxy(query_count)進(jìn)行name rebinding

補(bǔ)充

以上就是Python實(shí)現(xiàn)可調(diào)用對象裝飾的核心。

可調(diào)用對象包括函數(shù)、方法、實(shí)現(xiàn)了__call__方法的類,上述內(nèi)容只是針對函數(shù)來解釋,對于方法、實(shí)現(xiàn)了__call__方法的類,其基本原理相同,具體實(shí)現(xiàn)略有差別。

以上就是Python Decorator的設(shè)計(jì)模式演繹過程解析的詳細(xì)內(nèi)容,更多關(guān)于Python Decorator設(shè)計(jì)模式的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Pygame實(shí)現(xiàn)簡易版趣味小游戲之反彈球

    Pygame實(shí)現(xiàn)簡易版趣味小游戲之反彈球

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡易版趣味反彈球游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Tensorflow 實(shí)現(xiàn)線性回歸模型的示例代碼

    Tensorflow 實(shí)現(xiàn)線性回歸模型的示例代碼

    這篇文章主要介紹了Tensorflow 實(shí)現(xiàn)線性回歸模型,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 用Python調(diào)用win命令行提高工作效率的實(shí)例

    用Python調(diào)用win命令行提高工作效率的實(shí)例

    今天小編就為大家分享一篇用Python調(diào)用win命令行提高工作效率的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • python實(shí)現(xiàn)百度關(guān)鍵詞排名查詢

    python實(shí)現(xiàn)百度關(guān)鍵詞排名查詢

    這篇文章主要介紹了python實(shí)現(xiàn)百度關(guān)鍵詞排名查詢,需要的朋友可以參考下
    2014-03-03
  • python 通過SSHTunnelForwarder隧道連接redis的方法

    python 通過SSHTunnelForwarder隧道連接redis的方法

    今天小編就為大家分享一篇python 通過SSHTunnelForwarder隧道連接redis的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • python空值填充為無的實(shí)現(xiàn)方法

    python空值填充為無的實(shí)現(xiàn)方法

    我們經(jīng)常會(huì)遇到數(shù)據(jù)集中存在空值的情況,本文主要介紹了python空值填充為無的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • 詳解python日期時(shí)間處理2

    詳解python日期時(shí)間處理2

    這篇文章主要為大家介紹了python日期時(shí)間處理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • python 讀寫中文json的實(shí)例詳解

    python 讀寫中文json的實(shí)例詳解

    這篇文章主要介紹了 python 讀寫中文json的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家掌握這樣的內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • Python 如何給圖像分類(圖像識(shí)別模型構(gòu)建)

    Python 如何給圖像分類(圖像識(shí)別模型構(gòu)建)

    這篇文章主要介紹了Python 教你如何給圖像分類,今天的文章主要是講圖像識(shí)別模型如何構(gòu)建,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Python命令行運(yùn)行文件的實(shí)例方法

    Python命令行運(yùn)行文件的實(shí)例方法

    在本篇文章里小編給大家整理的是一篇關(guān)于Python命令行運(yùn)行文件的實(shí)例方法,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-03-03

最新評(píng)論