中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Python裝飾器進階

裝飾器進階

前言

如果你還不知道什么是裝飾器,請看這里,

請讀者不要感到文章的冗長無聊,我會盡量用生動的表達,但我保證這是你見過最詳細的教程(之一),如果你看完不能理解,歡迎在評論區(qū)批評我

給裝飾器傳參數(shù)-1

正如之前所說,裝飾器就是函數(shù),那么是函數(shù)就肯定可以傳參數(shù).

其實裝飾器在調(diào)用時本身就把它所裝飾的函數(shù)作為參數(shù)傳給了它,只是沒有很明白的寫出來而已,而下面我要介紹的是"看得見的參數(shù)傳遞過程".

使用場景模擬

現(xiàn)在假設老板需要一個功能,要把一個函數(shù)結(jié)果(可能是爬蟲獲取的數(shù)據(jù))發(fā)送給某個客戶.你很自然的想到用裝飾器來實現(xiàn),但是有個問題,老板的客戶很多,他隨時可能更換發(fā)送的客戶,這也就意味著你不能把客戶給"寫定",那么把客戶作為裝飾器的參數(shù)就顯得十分必要了.

(我把與裝飾器無關(guān)的功能用文字來代替了)

你想象中代碼樣子和功能

@sendMsgTo("老王")def spider():    return "爬到的數(shù)據(jù)"spider()

out:

已把 爬到的數(shù)據(jù) 發(fā)送給老王
@sendMsgTo("老胡")def spider():    return "爬到的數(shù)據(jù)"spider()

out:

已把 爬到的數(shù)據(jù) 發(fā)送給老王

給裝飾器傳參數(shù)-2

之前介紹過,當函數(shù)名后面跟上括號后代表執(zhí)行該函數(shù)的意思,而普通裝飾器的語法是不帶括號的(可以理解為:就是把這個函數(shù)拿來裝飾,而不是這個函數(shù)的執(zhí)行結(jié)果)

既然我們知道了@符后面跟的是函數(shù)(名),而不是函數(shù)的執(zhí)行結(jié)果,那么我們該怎么實現(xiàn)上面例子的效果呢?

很簡單:只要使上面例子中的sendMsgTo(XX)返回一個符合裝飾器語法的函數(shù)就可以啦!

符合裝飾器語法的函數(shù)長這樣:

def decorator(func):    def wrapper(*args, **kwargs):        func(*args, **kwargs)        '''        一些其他操作        '''    return wrapper

如果要返回上面的這個函數(shù),那就必須這么寫:

def returnDecorator():    def decorator(func):        def wrapper(*args, **kwargs):            func(*args, **kwargs)            '''            一些其他操作            '''        return wrapper    return decorator

就是加個一頭一尾的事情,當然,最外層函數(shù)的參數(shù),變量等等內(nèi)層的函數(shù)都是可以使用的

給裝飾器傳參數(shù)-3

有了上面的理解,那么我們來完善最開始我們需要的裝飾器吧!

def sendMsgTo(name):  # 定義外層函數(shù),可以接收額外參數(shù)    def decorator(func):    # 定義內(nèi)存函數(shù)實際上就是裝飾器        def wrapper(*args, **kwargs):              data = func(*args, **kwargs)              print("以把 {} 發(fā)送給{}".format(data, name))    # 調(diào)用外層函數(shù)傳進來的參數(shù)        return wrapper      return decorator    # 返回這個裝飾器@sendMsgTo("老王")def spider():    return "爬到的數(shù)據(jù)"if __name__ == '__main__':    spider()

out:

以把 爬到的數(shù)據(jù) 發(fā)送給老王

分析:

  1. @sendMsgTo("老王")這句話執(zhí)行了sendMsgTo這個函數(shù),并把老王作為參數(shù).
  2. sendMsgTo的作用實際上就是定義了一個裝飾器函decorator并把該裝飾器返回.
  3. 這樣做的目的是使其內(nèi)部裝飾器函數(shù)能夠接收外面?zhèn)鬟M來的參數(shù)(這個例子中是name)
  4. 從而達到給裝飾器傳參的目的.
  5. 但我們都清楚sendMsgTo并不是真正的裝飾器,他只是負責接收外界的參數(shù)來構(gòu)造真正的裝飾器并返回.因為真正的裝飾器函數(shù)是只能有一個參數(shù),那就是被裝飾的函數(shù)

用類來寫一個裝飾器-1

在這之前,我們都是通過函數(shù)來實現(xiàn)裝飾器的功能,從現(xiàn)在起教大家使用類來實現(xiàn)裝飾器的功能,這樣一來就可以添加更多的功能(雖然絕大多數(shù)情況下使用函數(shù)裝飾器也可以做,但是代碼的可讀性不高,因為所有功能都集中在一個函數(shù)中,使用類裝飾器就可以把功能單獨作為類的方法,使用時調(diào)用方法即可)

class AAA(object):    def __call__(self, func):        def wrapper():            print(func())            print("這是類裝飾器給你的附加功能")        return wrapper@AAA()def spider():    return "爬到的數(shù)據(jù)"if __name__ == '__main__':    spider()

out:

爬到的數(shù)據(jù)這是類裝飾器給你的附加功能

注意:

  1. 使用類來實現(xiàn)裝飾器必須實現(xiàn)__call__方法(其實也不是強制)

  2. 調(diào)用類裝飾器時要加(),這不是調(diào)用函數(shù)的意思,這是實例化對象的意思

  3. 實例化對象后Python會自動調(diào)用__call__方法作為裝飾器(本質(zhì)還是函數(shù)),如果你不實現(xiàn)__call__方法那么就需要你自己手動調(diào)用了,舉個例子:

    class AAA(object):    def myDec(self, func):        def wrapper():            print(func())            print("這是類裝飾器給你的附加功能")        return wrapperaaa = AAA()@aaa.myDecdef spider():    return "爬到的數(shù)據(jù)"if __name__ == '__main__':    spider()

    及其不推薦這種寫法,一個字

用類來寫一個裝飾器-2

通過上面的介紹,我相信你們都理解了怎么使用類來寫一個裝飾器(其實本質(zhì)還是函數(shù)),那么我們就在最開始的例子上加點要求.

附加要求:現(xiàn)在老板覺得直接把數(shù)據(jù)發(fā)給客戶不太穩(wěn)重,他想先檢查一下數(shù)據(jù)是否存在敏感信息,將其去除后再發(fā)送

使用類裝飾器來完成:

class sendMsgTo(object):  # 函數(shù)參數(shù)    def __init__(self, name):        self.name = name    def __call__(self, func):        def wrapper(*args, **kwargs):              data = func(*args, **kwargs)              data = self.washData(data)            print("以把 {} 發(fā)送給{}".format(data, self.name))        return wrapper      def washData(self, data):        '''        負責清洗數(shù)據(jù),去除敏感信息        這里把 `數(shù)據(jù)` 兩個字去除換成 `東西`        '''        return data.replace("數(shù)據(jù)", "東西")@sendMsgTo("老王")def spider():    return "爬到的數(shù)據(jù)"if __name__ == '__main__':    spider()

out:

以把 爬到的東西 發(fā)送給老王

為了加深讀者對類裝飾器的理解,我希望讀者可以結(jié)合前面說過的內(nèi)容自己來理一遍上面代碼的執(zhí)行順序和邏輯,這并不難.

沒想到你能堅持看到這里

如果你看不懂歡迎評論留言,

往期精彩:深入淺出Python裝飾器,Python爬蟲之解析網(wǎng)頁,PyMySQL學習筆記

來源:http://www.icode9.com/content-1-250601.html
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
python裝飾器示例
Python裝飾器和符號@ | Hom
理解 Python 裝飾器看這一篇就夠了 – 碼農(nóng)網(wǎng)
說說 Python 中的閉包
干貨分享 | 理解 Python 裝飾器的簡單方法
Python 裝飾器
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服