婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > python中的裝飾器該如何使用

python中的裝飾器該如何使用

熱門標簽:百度地圖標注位置怎么修改 梅州外呼業務系統 地圖標注視頻廣告 高德地圖標注是免費的嗎 無錫客服外呼系統一般多少錢 老人電話機器人 大連crm外呼系統 洪澤縣地圖標注 北京電信外呼系統靠譜嗎

1. 需求是怎么來的

裝飾器的定義很是抽象,我們來看一個小例子。

def foo():
    print('in foo()')
foo()

這是一個很無聊的函數沒錯。但是突然有一個更無聊的人,我們稱呼他為B君,說我想看看執行這個函數用了多長時間,好吧,那么我們可以這樣做:

import time

def foo():
    start = time.time()
    print('in foo()')
    time.sleep(2)
    end = time.time()
    print(f'used:{end - start}')

foo()

很好,功能看起來無懈可擊。可是蛋疼的B君此刻突然不想看這個函數了,他對另一個叫foo2的函數產生了更濃厚的興趣。

怎么辦呢?如果把以上新增加的代碼復制到foo2里,這就犯了大忌了~復制什么的難道不是最討厭了么!而且,如果B君繼續看了其他的函數呢?

2. 以不變應萬變,是變也

還記得嗎,函數在Python中是一等公民,那么我們可以考慮重新定義一個函數timeit,將foo的引用傳遞給他,然后在timeit中調用foo并進行計時,這樣,我們就達到了不改動foo定義的目的,而且,不論B君看了多少個函數,我們都不用去修改函數定義了!

import time

def foo():
    print('in foo()')

def timeit(func):
    start = time.time()
    func()
    time.sleep(2)
    end = time.time()
    print('used:', end - start)

timeit(foo)

看起來邏輯上并沒有問題,一切都很美好并且運作正常!……等等,我們似乎修改了調用部分的代碼。原本我們是這樣調用的:foo(),修改以后變成了:timeit(foo)。這樣的話,如果foo在N處都被調用了,你就不得不去修改這N處的代碼。或者更極端的,考慮其中某處調用的代碼無法修改這個情況,比如:這個函數是你交給別人使用的。

3. 最大限度地少改動

既然如此,我們就來想想辦法不修改調用的代碼;如果不修改調用代碼,也就意味著調用foo()需要產生調用timeit(foo)的效果。我們可以想到將timeit賦值給foo,但是timeit似乎帶有一個參數……想辦法把參數統一吧!如果timeit(foo)不是直接產生調用效果,而是返回一個與foo參數列表一致的函數的話……就很好辦了,將timeit(foo)的返回值賦值給foo,然后,調用foo()的代碼完全不用修改!

# -*- coding: UTF-8 -*-
import time

def foo():
    print('in foo()')

# 定義一個計時器,傳入一個,并返回另一個附加了計時功能的方法
def timeit(func):
    # 定義一個內嵌的包裝函數,給傳入的函數加上計時功能的包裝
    def wrapper():
        start = time.time()
        func()
        time.sleep(2)
        end = time.time()
        print('used:', end - start)

    # 將包裝后的函數返回
    return wrapper

foo = timeit(foo)
foo()

這樣,一個簡易的計時器就做好了!我們只需要在定義foo以后調用foo之前,加上foo = timeit(foo),就可以達到計時的目的,這也就是裝飾器的概念,看起來像是foo被timeit裝飾了。在在這個例子中,函數進入和退出時需要計時,這被稱為一個橫切面(Aspect),這種編程方式被稱為面向切面的編程(Aspect-Oriented Programming)。與傳統編程習慣的從上往下執行方式相比較而言,像是在函數執行的流程中橫向地插入了一段邏輯。在特定的業務領域里,能減少大量重復代碼。面向切面編程還有相當多的術語,這里就不多做介紹,感興趣的話可以去找找相關的資料。

這個例子僅用于演示,并沒有考慮foo帶有參數和有返回值的情況,完善它的重任就交給你了 :)

上面這段代碼看起來似乎已經不能再精簡了,Python于是提供了一個語法糖來降低字符輸入量。

import time


def timeit(func):
    def wrapper():
        start = time.time()
        func()
        time.sleep(2)
        end = time.time()
        print('used:', end - start)

    return wrapper


@timeit
def foo():
    print('in foo()')


foo()

重點關注第11行的@timeit,在定義上加上這一行與另外寫foo = timeit(foo)完全等價,千萬不要以為@有另外的魔力。除了字符輸入少了一些,還有一個額外的好處:這樣看上去更有裝飾器的感覺。

看到這里其實你也明白了,python 中的裝飾器本質上就是一個函數,這個函數接收其他的函數作為參數,并將其以一個全新的修改后的函數替換它。

4.對帶參數的函數使用裝飾器

如果要包裝的函數有參數,也不麻煩,只要內嵌包裝函數的形參和返回值與原函數相同,裝飾函數返回內嵌包裝函數對象就可以啦

import datetime,time

def out(func):
    def inner(*args):
        start = datetime.datetime.now()
        func(*args)
        end = datetime.datetime.now()
        print(end-start)
        print("out and inner")
    return inner

@out
def myfunc(*args):
    time.sleep(1)
    print("args is{}".format(args))

myfunc("lalalal")

5. 給裝飾器參數

給裝飾器傳參也不難,和上一示例相比在外層多了一層包裝而已

#coding:utf-8
def outermost(*args):
	def out(func):
		print ("裝飾器參數{}".format(args))
		def inner(*args):
			print("innet start")
			func(*args)
			print ("inner end")
		return inner
	return out

@outermost(666)
def myfun(*args):
	print ("試試裝飾器和函數都帶參數的情況,被裝飾的函數參數{}".format(args))

myfun("zhangkun")

6.帶類參數的裝飾器

參數是什么類型其實都不影響的,你看,參數是個類也一樣的

class locker:
    def __init__(self):
        print("locker.__init__() should be not called")

    @staticmethod
    def acquire():
        print("locker.acquire() static method be called")

    @staticmethod
    def release():
        print("locker.release() static method be called")

def outermost(cls):
    def out(func):
        def inner():
            cls.acquire()
            func()
            cls.release()
        return inner
    return out

@outermost(locker)
def myfunc():
    print("myfunc called")

myfunc()

7. 對一個函數應用多個裝飾器

一個函數可以擁有多個裝飾器,但是要注意順序

class mylocker:
    def __init__(self):
        print("mylocker.__init__() called.")

    @staticmethod
    def acquire():
        print("mylocker.acquire() called.")

    @staticmethod
    def unlock():
        print("  mylocker.unlock() called.")

class lockerex(mylocker):
    @staticmethod
    def acquire():
        print("lockerex.acquire() called.")

    @staticmethod
    def unlock():
        print("  lockerex.unlock() called.")

def lockhelper(cls):
    def _deco(func):
        def __deco2(*args, **kwargs):
            print("before %s called." % func.__name__)
            cls.acquire()
            try:
                return func(*args, **kwargs)
            finally:
                cls.unlock()
        return __deco2
    return _deco

class example:
    @lockhelper(mylocker)
    @lockhelper(lockerex)
    def myfunc2(self, a, b):
        print(" myfunc2() called.")
        print(a+b)

a = example()
a.myfunc2(1,2)

8. 作為一個類

雖然裝飾器幾乎總是可以用函數實現,但是在某些情況下,使用用戶自定義的類可能會更好

import time


class DerocatorAsClass:
    def __init__(self,funcation):
        self.funcation = funcation

    def __call__(self, *args, **kwargs):
        # 調用函數之前,做點什么
        result = self.funcation(*args,**kwargs)
        print('3333333333')
        # 在調用之后做點什么并且返回結果
        return result

@DerocatorAsClass
def foo():
    print('in foo()')


foo()

如上例,用類作為裝飾器也是很方便的

以上就是python中的裝飾器該如何使用的詳細內容,更多關于python 裝飾器的使用的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • 如何正確理解python裝飾器
  • Python必備基礎之閉包和裝飾器知識總結
  • python 裝飾器的使用與要點
  • Python pytest裝飾器總結(實例詳解)
  • Python 的lru_cache裝飾器使用簡介
  • python裝飾器代碼深入講解
  • python 裝飾器重要在哪
  • Python 中的函數裝飾器和閉包詳解
  • 詳解Python模塊化編程與裝飾器
  • python 裝飾器的基本使用
  • Python高階函數與裝飾器函數的深入講解

標簽:長春 安慶 洛陽 吉林 清遠 怒江 岳陽 泉州

巨人網絡通訊聲明:本文標題《python中的裝飾器該如何使用》,本文關鍵詞  python,中的,裝飾,器該,如何,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《python中的裝飾器該如何使用》相關的同類信息!
  • 本頁收集關于python中的裝飾器該如何使用的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    91热门视频在线观看| 99国产精品久| 亚洲电影激情视频网站| 精品一区二区影视| 99久久精品国产网站| 精品国产免费视频| 五月婷婷综合网| 国产91色综合久久免费分享| 国产.精品.日韩.另类.中文.在线.播放 | 欧美国产精品一区| 精品成人一区二区三区四区| 日韩美女视频19| 本田岬高潮一区二区三区| 欧美视频一区在线观看| 亚洲图片你懂的| 色综合 综合色| 亚洲精品欧美激情| 欧美午夜精品理论片a级按摩| 欧美变态tickling挠脚心| 亚洲欧美电影院| jlzzjlzz国产精品久久| 国产精品人人做人人爽人人添| 美女视频网站黄色亚洲| 国产精品乱子久久久久| 美女脱光内衣内裤视频久久网站| 欧美片网站yy| 精品亚洲成a人| 国产日韩欧美精品电影三级在线 | 亚洲精品欧美在线| 色综合久久六月婷婷中文字幕| 亚洲色图视频网站| 91精品麻豆日日躁夜夜躁| 国产精品主播直播| 26uuu另类欧美| 99re视频精品| 久久国内精品视频| 成人免费在线视频观看| 国产夫妻精品视频| 日本午夜精品视频在线观看| 国产精品久久毛片a| 日韩制服丝袜av| 精品视频在线视频| 日韩女优av电影在线观看| 国产精品一区二区免费不卡| 欧美videos中文字幕| 日本一区二区三区视频视频| 亚洲黄色片在线观看| 久久国产福利国产秒拍| av在线播放一区二区三区| 久久久三级国产网站| 亚洲三级免费观看| 国内一区二区视频| 在线播放91灌醉迷j高跟美女 | 成人理论电影网| 91超碰这里只有精品国产| 国产精品美女久久久久aⅴ| 全国精品久久少妇| 欧美在线免费视屏| 国产精品天天摸av网| 久久精品国产在热久久| 波多野结衣中文字幕一区二区三区| 欧美一区永久视频免费观看| 亚洲人成影院在线观看| 国产一区二区三区四区五区入口| 欧美精品精品一区| 一区二区视频免费在线观看| 国产.欧美.日韩| 久久久久久久网| 久久99国产精品久久| 国产成人综合在线观看| 精品少妇一区二区三区在线播放 | 欧美巨大另类极品videosbest| 日韩美女啊v在线免费观看| 亚洲制服丝袜一区| 一本大道久久a久久综合婷婷| 欧美国产日韩一二三区| 国内精品视频666| 欧美成人午夜电影| 麻豆视频一区二区| 日韩一区二区电影网| 天天综合网天天综合色| 欧美日韩不卡一区| 午夜精品久久久久影视| 色婷婷久久综合| 99精品视频中文字幕| 国产精品久久久久桃色tv| 99re热视频精品| 日韩中文字幕av电影| 国产亚洲精久久久久久| 91久久精品网| 极品销魂美女一区二区三区| 18成人在线观看| 日韩欧美在线影院| 91丝袜美女网| aaa国产一区| 亚洲1区2区3区4区| 欧美xxxxx牲另类人与| 懂色av一区二区夜夜嗨| 日韩不卡在线观看日韩不卡视频| 国产午夜精品福利| 欧美精品视频www在线观看| 成人一级片在线观看| 免费国产亚洲视频| 亚洲国产欧美一区二区三区丁香婷| 精品国免费一区二区三区| 欧亚洲嫩模精品一区三区| 国产美女精品在线| 日本在线不卡视频| 亚洲在线免费播放| 亚洲国产高清在线| 日韩欧美一区二区视频| 日本高清无吗v一区| 国产69精品久久久久毛片| 麻豆免费看一区二区三区| 亚洲成年人影院| 亚洲欧美日韩精品久久久久| 精品福利一二区| 在线视频国内自拍亚洲视频| 成人精品视频一区二区三区尤物| 久久精品理论片| 日韩影院在线观看| 一区二区三区日韩欧美精品| 久久精品男人天堂av| 欧美一区二区视频在线观看| 欧美在线不卡视频| 在线看国产一区二区| 色欧美日韩亚洲| 国产成人无遮挡在线视频| 激情偷乱视频一区二区三区| 久久国产尿小便嘘嘘| 男人的天堂久久精品| 亚洲18色成人| 天堂一区二区在线免费观看| 亚洲综合免费观看高清完整版在线| 国产精品久久福利| 国产精品国产a| 国产精品天美传媒| 中文字幕欧美日韩一区| 国产精品水嫩水嫩| 亚洲欧洲99久久| 亚洲精品伦理在线| 亚洲午夜电影网| 亚洲电影第三页| 亚洲成av人片在线观看| 青青草91视频| 国产一区二区三区黄视频 | 色呦呦日韩精品| 一本久久综合亚洲鲁鲁五月天| 99re在线精品| 欧美亚洲另类激情小说| 欧美日免费三级在线| 欧美精品日韩一区| 26uuuu精品一区二区| 久久精品夜色噜噜亚洲a∨| 国产精品入口麻豆原神| 亚洲精品国产精品乱码不99| 亚洲h精品动漫在线观看| 青青草国产精品亚洲专区无| 久久se这里有精品| 成人在线一区二区三区| 在线欧美小视频| 日韩精品中文字幕在线一区| 久久一留热品黄| 亚洲人123区| 日韩成人av影视| 成人免费视频视频| 欧美性三三影院| 久久色视频免费观看| 国产精品不卡在线| 免费在线看成人av| 成人一区二区三区中文字幕| 欧美偷拍一区二区| 久久综合av免费| 亚洲激情图片一区| 久热成人在线视频| 一本一道波多野结衣一区二区| 日韩一二三区视频| 亚洲欧洲av在线| 久久99国产精品久久| 99精品久久99久久久久| 欧美一级夜夜爽| 亚洲欧美日韩一区| 国产在线不卡一区| 欧美中文字幕亚洲一区二区va在线| 日韩免费观看高清完整版| 日韩伦理免费电影| 国产主播一区二区三区| 欧美视频三区在线播放| 国产欧美一区二区精品仙草咪| 亚洲国产精品人人做人人爽| 国产成人综合自拍| 色狠狠色噜噜噜综合网| 久久久久成人黄色影片| 日韩福利视频导航| 日本高清视频一区二区| 九色综合狠狠综合久久| 欧美主播一区二区三区美女| 中文字幕乱码久久午夜不卡 | 91精品一区二区三区在线观看| 国产日韩一级二级三级|