成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Python - 裝飾器decorator

HackerShell / 1262人閱讀

摘要:在這種代碼運(yùn)行期間動(dòng)態(tài)增加功能的方式,稱之為裝飾器。四接收特定類型參數(shù)的裝飾器裝飾器可以接收參數(shù),當(dāng)調(diào)用裝飾器返回的函數(shù)時(shí),也就調(diào)用了包裹函數(shù),把參數(shù)傳入包裹函數(shù),它將參數(shù)傳遞給被裝飾的函數(shù)。執(zhí)行結(jié)果執(zhí)行結(jié)果


【題外話】心塞塞 心情down down down 有段時(shí)間沒(méi)用裝飾器了,然后然后問(wèn)著就跪了~~~
回來(lái)翻了翻資料和代碼......


一、什么是裝飾器
裝飾器,decorator,本質(zhì)上是一個(gè)Python函數(shù),它可以讓其他函數(shù)在不需要做任何代碼變動(dòng)的前提下增加額外功能,裝飾器的返回值也是一個(gè)函數(shù)對(duì)象。

裝飾器通過(guò)不修改核心代碼而增強(qiáng)核心代碼部分的功能。例如在函數(shù)前插入日志、權(quán)限校驗(yàn)、事務(wù)處理等場(chǎng)景。
而且可以抽離出大量與函數(shù)功能無(wú)關(guān)的雷同代碼并重用。

二、早期實(shí)現(xiàn):不是裝飾器的裝飾器

Python中函數(shù)也可以看做是一個(gè)對(duì)象,可以賦值給變量,并通過(guò)變量調(diào)用該函數(shù)。

例如:

def foo():
   print("2017-06-08")
f = foo    # 將函數(shù)賦值給變量,f為函數(shù)對(duì)象
f()
# 返回結(jié)果:
2017-06-08
三、語(yǔ)法糖@ 實(shí)現(xiàn)簡(jiǎn)單裝飾器

假設(shè)現(xiàn)在要增強(qiáng)foo()的功能,例如,在函數(shù)調(diào)用前打印日志。但是又不希望修改foo()函數(shù)的定義。在這種代碼運(yùn)行期間動(dòng)態(tài)增加功能的方式,稱之為“裝飾器”。
如下:

def testfunc(func):
    print("testfunc")
    def wrapper():
        print("%s %s() called" %(time.ctime(),func.__name__))
        return func()
    return wrapper
@testfunc 
def foo():
    print("foo1()")

foo()  # 相當(dāng)于執(zhí)行testfunc(foo) ->wrapper(foo) -> foo()

執(zhí)行結(jié)果:

testfunc
Wed Sep 12 15:01:13 2018 foo() called
foo1()

說(shuō)明:執(zhí)行foo()前,先執(zhí)行testfunc(foo),再執(zhí)行wrapper(),返回時(shí)調(diào)用foo()本身。

四、接收特定類型參數(shù)的裝飾器

裝飾器可以接收參數(shù),當(dāng)調(diào)用裝飾器返回的函數(shù)時(shí),也就調(diào)用了包裹函數(shù),把參數(shù)傳入包裹函數(shù),它將參數(shù)傳遞給被裝飾的函數(shù)。

如下:

def testfunc_with_args(func):
    def wrapper_argus(arg1, arg2):
        print("I got args! Look:", arg1, arg2)
        func(arg1, arg2)
    return wrapper_argus
@testfunc_with_args
def full_name(first_name, last_name):  # 帶參數(shù),將參數(shù)傳給被裝飾的函數(shù)
    print("My name is", first_name, last_name)

full_name("Peter", "Venkman")  # 調(diào)用

執(zhí)行結(jié)果:

I got args! Look: Peter Venkman
My name is Peter Venkman
五、帶不定參數(shù)的裝飾器

當(dāng)有多個(gè)函數(shù)需要調(diào)用裝飾器,但是函數(shù)的參數(shù)各不同時(shí),該如何實(shí)現(xiàn)呢?總不能一個(gè)函數(shù)對(duì)應(yīng)一個(gè)裝飾器吧。這時(shí)候就可以用帶不定參數(shù)的裝飾器進(jìn)行實(shí)現(xiàn)。
如下:

def log(func):
    def wrapper(*args,**kwargs):        # 可接受各種參數(shù)
        print("call %s():"% func.__name__)
        return func(*args,**kwargs)     # 返回一個(gè)函數(shù)
    return wrapper                      # 裝飾器返回一個(gè)函數(shù),進(jìn)入到wrapper()

@log      # @log放到now()的定義處,相當(dāng)于執(zhí)行語(yǔ)句:now = log(now)
def now_1(a,b):
    print("now()1:a+b = ",a+b)
@log
def now_2(a,b,c):
    print("now_2():a+b+c = ",a+b+c)

now_1(1,2)
now_2(1,2,3)

運(yùn)行一下哦~

六、多個(gè)裝飾器

當(dāng)一個(gè)函數(shù)想要加入多項(xiàng)功能時(shí),可以考慮使用多層裝飾器,就是要注意一下裝飾器的執(zhí)行順序。
舉個(gè)栗子:

# 注意代碼的執(zhí)行順序
def deco_1(func):
    print("------111111------")
    def wrapper(*args,**kwargs):    # 包裹函數(shù),參數(shù)與原函數(shù)的參數(shù)一致
        print("start: this is deco_1.")
        func(*args,**kwargs)
        print("end: deco_1.")
    return wrapper  # 返回值是一個(gè)包裹函數(shù)
def deco_2(func):
    print("------222222------")
    def wrapper(*args,**kwargs):
        print("start: this is deco_2.")
        func(*args,**kwargs)
        print("end: deco_2.")
    return wrapper

@deco_1
@deco_2
def now_1(a,b):
    print("now()1:a+b = ",a+b)

now_1(1,2)

運(yùn)行結(jié)果:

# 結(jié)果,注意執(zhí)行順序:
------222222------
------111111------
start: this is deco_1.
start: this is deco_2.
now()1:a+b =  3
end: deco_2.
end: deco_1.
七、裝飾器本身帶參數(shù)

除了給被裝飾的函數(shù)帶參數(shù),裝飾器本身也可以帶參數(shù)。

def logging(level):
    def wrapper(func):
        def inner_wrapper(*args, **kwargs):
            print("[{level}]: enter function {func}()".format(level=level, func=func.__name__))
            return func(*args, **kwargs)
        return inner_wrapper
    return wrapper
    
@logging(level="INFO")
def say(something):
    print("say {}!".format(something))

@logging(level="DEBUG")
def do(something):
    print("do {}...".format(something))

say("hello")
do("my work")

執(zhí)行結(jié)果:

# 執(zhí)行結(jié)果:
[INFO]: enter function say()
say hello!
[DEBUG]: enter function do()
do my work...

? thanks for watching, keep on updating...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/42421.html

相關(guān)文章

  • python 裝飾 part2

    摘要:裝飾器傳參被裝飾的函數(shù)帶有參數(shù)的情況接上一篇,直接上代碼函數(shù)也就是被裝飾的函數(shù)的運(yùn)行時(shí)間是裝飾器的正確使用,不需要傳參裝飾器的正確使用,需要傳參此時(shí)不用再像上面一樣賦值,可以直接調(diào)用返回值被裝飾的函數(shù)有返回值在裝飾器內(nèi)部需被裝飾函數(shù)的調(diào)用 python 裝飾器 傳參 被裝飾的函數(shù)帶有參數(shù)的情況 接上一篇,直接上代碼 import time def decorator(func): ...

    sanyang 評(píng)論0 收藏0
  • Python裝飾

    摘要:一引用書(shū)流暢的書(shū)二基本概念問(wèn)題裝飾器是什么解答嚴(yán)格來(lái)說(shuō),裝飾器只是語(yǔ)法糖,裝飾器是可調(diào)用的對(duì)象,可以像常規(guī)的可調(diào)用對(duì)象那樣調(diào)用,特殊的地方是裝飾器的參數(shù)是一個(gè)函數(shù)問(wèn)題裝飾器有什么特性解答裝飾器有個(gè)特性,一是可以把被裝飾的函數(shù)替換成其他函數(shù), 一, 引用 [書(shū)] 流暢的Python [書(shū)] Effective Python 二, 基本概念 showImg(https://segme...

    aisuhua 評(píng)論0 收藏0
  • Python 裝飾使用指南

    摘要:裝飾器是可調(diào)用的對(duì)象,其參數(shù)是另一個(gè)函數(shù)被裝飾的函數(shù)。第二大特性是,裝飾器在加載模塊時(shí)立即執(zhí)行。另一個(gè)常見(jiàn)的裝飾器是,它的作用是協(xié)助構(gòu)建行為良好的裝飾器。 裝飾器是可調(diào)用的對(duì)象,其參數(shù)是另一個(gè)函數(shù)(被裝飾的函數(shù))。 裝飾器基礎(chǔ)知識(shí) 首先看一下這段代碼 def deco(fn): print I am %s! % fn.__name__ @deco def func(): ...

    NeverSayNever 評(píng)論0 收藏0
  • Python知識(shí)點(diǎn):理解和使用裝飾 @decorator

    摘要:使用類裝飾器,優(yōu)點(diǎn)是靈活性大,高內(nèi)聚,封裝性。不過(guò)不用擔(dān)心,有,本身也是一個(gè)裝飾器,它的作用就是把原函數(shù)的元信息拷貝到裝飾器函數(shù)中,使得裝飾器函數(shù)也有和原函數(shù)一樣的元信息。 showImg(https://segmentfault.com/img/bVbrFWb?w=742&h=484);Python的裝飾器(decorator)是一個(gè)很棒的機(jī)制,也是熟練運(yùn)用Python的必殺技之一。...

    cyqian 評(píng)論0 收藏0
  • Python裝飾vs裝飾模式

    摘要:希望引以為戒鄭傳裝飾模式如果你了解,你肯定聽(tīng)過(guò)裝飾器模式。在面向?qū)ο笾?,裝飾模式指動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加一些功能來(lái)說(shuō),裝飾模式比生成子類更為靈活。 漫談 如果作為一個(gè)Python入門,不了解Python裝飾器也沒(méi)什么,但是如果作為一個(gè)中級(jí)Python開(kāi)發(fā)人員,如果再不對(duì)python裝飾器熟稔于心的話,那么可能并沒(méi)有量變積累到質(zhì)變。 我以前也看過(guò)很多講python 裝...

    stackvoid 評(píng)論0 收藏0
  • python裝飾詳解

    摘要:為了避免重復(fù)調(diào)用,可以適當(dāng)?shù)刈鼍彺妫难b飾器可以完美的完成這一任務(wù)。這意味著我們可以為方法創(chuàng)建裝飾器,只是要記得考慮。裝飾器封裝了函數(shù),這使得調(diào)試函數(shù)變得困難。另外,使用裝飾器去管理緩存和權(quán)限。 原文地址 之前用python簡(jiǎn)單寫了一下斐波那契數(shù)列的遞歸實(shí)現(xiàn)(如下),發(fā)現(xiàn)運(yùn)行速度很慢。 def fib_direct(n): assert n > 0, invalid n ...

    maybe_009 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

HackerShell

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<