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

Python?Decorator的設計模式演繹過程解析

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

關于代理模式、裝飾模式

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

這兩者都是通過在原有對象的基礎上封裝一層對象,通過調用封裝后的對象而不是原來的對象來實現(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("事務處理之前");
        // 調用委托類的方法;
        countImpl.queryCount();
        System.out.println("事務處理之后");
    }
    @Override
    public void updateCount() {
        System.out.println("事務處理之前");
        // 調用委托類的方法;
        countImpl.updateCount();
        System.out.println("事務處理之后");
    }
}

在這個例子中CountProxy是對CountImpl的封裝。

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

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

如果強調通過CountProxy 對CountImpl進行代理的作用,則稱為代理模式;

如果強調通過CountProxy 對CountImpl增加額外的操作,則稱為裝飾模式;

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

其封裝的目的在于增強所封裝對象的功能或管理所封裝的對象。

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

Python中的代理/裝飾

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

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

因此,當代理/裝飾的對象是函數(shù)時,可以使用高階函數(shù)來對某個函數(shù)進行封裝。

例如:

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)

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

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

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

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僅負責接受被代理的函數(shù)query_count作為參數(shù),同時,返回一個函數(shù)對象wrapper作為返回值,真正的封裝動作在wrapper這個函數(shù)中完成。

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

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

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

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

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

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

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

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

對,就是query_count = query_count_proxy(query_count),因為這句既不簡潔,又屬于重復工作。

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ù)的時候,在其前面加上@query_count_proxy。

Python看到這樣的語法,就會自動的執(zhí)行query_count = query_count_proxy(query_count)進行name rebinding

補充

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

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

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

相關文章

  • Python格式化字符串的案例方法

    Python格式化字符串的案例方法

    在編寫程序的過程中,經(jīng)常需要進行格式化輸出,每次用每次查,干脆就在這里整理一下,下面這篇文章主要給大家介紹了關于python字符串格式化的相關資料,分別是%格式符和format方式,需要的朋友可以參考下
    2022-03-03
  • Python的Scrapy框架中的CrawlSpider介紹和使用

    Python的Scrapy框架中的CrawlSpider介紹和使用

    這篇文章主要介紹了Python的Scrapy框架中的CrawlSpider介紹和使用,CrawlSpider其實是Spider的一個子類,除了繼承到Spider的特性和功能外,還派生除了其自己獨有的更加強大的特性和功能,其中最顯著的功能就是"LinkExtractors鏈接提取器",需要的朋友可以參考下
    2023-12-12
  • python黑魔法之編碼轉換

    python黑魔法之編碼轉換

    這篇文章主要介紹了python黑魔法之編碼轉換,分析了python編碼轉換的方法,感興趣的小伙伴們可以參考一下
    2016-01-01
  • 兩行Python代碼實現(xiàn)pdf轉word功能

    兩行Python代碼實現(xiàn)pdf轉word功能

    這篇文章主要為大家詳細介紹了如何利用兩行Python代碼就能實現(xiàn)pdf轉word功能,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2023-03-03
  • 解決pyttsx3無法封裝的問題

    解決pyttsx3無法封裝的問題

    今天小編就為大家分享一篇解決pyttsx3無法封裝的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • Python中@property的理解和使用示例

    Python中@property的理解和使用示例

    這篇文章主要介紹了Python中@property的理解和使用,結合實例形式分析了Python中@property的功能、使用方法及相關操作注意事項,需要的朋友可以參考下
    2019-06-06
  • Python切片操作實例分析

    Python切片操作實例分析

    這篇文章主要介紹了Python切片操作,結合實例形式較為詳細的分析了Python切片相關的正向、反向、步長等使用技巧與相關注意事項,需要的朋友可以參考下
    2018-03-03
  • Python項目目錄找不到.git文件怎么刪除

    Python項目目錄找不到.git文件怎么刪除

    這篇文章主要介紹了Python項目目錄找不到.git文件怎么刪除的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • 淺析Python?pickle?包的理解和使用

    淺析Python?pickle?包的理解和使用

    pickle?是?Python?庫中的一個模塊,用于將?Python?對象序列化和反序列化,這篇文章主要介紹了Python?pickle?包的理解和使用,需要的朋友可以參考下
    2023-05-05
  • Python中使用Pillow庫生成立體文字的圖像

    Python中使用Pillow庫生成立體文字的圖像

    在眾多Python庫中,Pillow庫以其豐富的功能和易用性在圖像處理領域脫穎而出,Pillow是Python領域中最基礎且常用的圖像處理庫之一,,本文將詳細介紹如何使用Python自動生成帶有立體效果的文字,我們會逐步講解輸入文字、選擇字體和顏色,并應用立體效果來生成最終圖
    2025-03-03

最新評論

益阳市| 夏津县| 朔州市| 淮安市| 张掖市| 邢台市| 巴马| 宜兰市| 凉城县| 泸水县| 若尔盖县| 隆子县| 兴文县| 兴文县| 威宁| 华宁县| 金溪县| 台北县| 利辛县| 崇文区| 大理市| 甘南县| 北川| 建瓯市| 新津县| 巨鹿县| 兰溪市| 丹巴县| 丰台区| 班戈县| 旬阳县| 上杭县| 金寨县| 定襄县| 文成县| 婺源县| 建宁县| 灌南县| 乌拉特后旗| 孝感市| 民丰县|