亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

python編程之函數(shù)裝飾器語(yǔ)法原理以及參數(shù)傳遞詳解

系統(tǒng) 2026 0

? ? ? ?筆者之前寫(xiě)過(guò)一篇簡(jiǎn)單介紹python函數(shù)裝飾器用法的文章,本文便不再贅述。簡(jiǎn)而言之,pythong函數(shù)裝飾器是一種通過(guò)特定語(yǔ)法,給函數(shù)額外增加一層邏輯,以實(shí)現(xiàn)相應(yīng)目的的一種語(yǔ)法結(jié)構(gòu)。本文將介紹裝飾器的原理、被裝飾函數(shù)是如何以參數(shù)的形式傳入到裝飾器函數(shù)內(nèi)部的,以及實(shí)現(xiàn)給裝飾器函數(shù)設(shè)定參數(shù)的參數(shù)傳遞原理。

            
              def decorator(func):
    def wrapper(*args,**kargs):
        print('I love Python!')
        func()
    return wrapper

@decorator
def fun():
    print('test')
            
          

? ? ? ?如上代碼,是一個(gè)典型的關(guān)于函數(shù)裝飾器的例子,但遺憾的是,這個(gè)例子其實(shí)說(shuō)明不了太多的東西,僅僅只是介紹了函數(shù)裝飾器的最簡(jiǎn)單的一種應(yīng)用方式而已。為了理解函數(shù)裝飾器,我們從最簡(jiǎn)單最直接的裝飾器構(gòu)造方式,一步步展開(kāi)。

            
              def decorator(func):
    print('just for testing')
    return func

@decorator
def fun():
    print('test')
            
          

? ? ? ?上面的代碼實(shí)際上也可以順利執(zhí)行,當(dāng)腳本運(yùn)行到@語(yǔ)句時(shí),便會(huì)把函數(shù)fun以參數(shù)的形式傳給decorator,然后裝飾器函數(shù)decorator便會(huì)運(yùn)行,運(yùn)行的結(jié)果就是執(zhí)行print,然后將fun返回給fun自己,因?yàn)檫@時(shí)裝飾器函數(shù)返回的函數(shù)就是fun本身,所以當(dāng)我們?cè)僬{(diào)用fun的時(shí)候,fun的行為和其定義的一樣,沒(méi)有任何變化。通過(guò)這個(gè)例子我們知道,實(shí)際上函數(shù)裝飾器的語(yǔ)法就是:通過(guò)@聲明裝飾器函數(shù),被裝飾函數(shù)作為參數(shù)傳給裝飾器函數(shù),然后裝飾器函數(shù)會(huì)執(zhí)行,執(zhí)行的最后需要返回一個(gè)函數(shù)給被裝飾函數(shù),即被裝飾的函數(shù)重綁定到裝飾器函數(shù)返回函數(shù)。換言之,@語(yǔ)句會(huì)直接執(zhí)行裝飾器函數(shù),然后返回一個(gè)函數(shù)給被裝飾器函數(shù),而這個(gè)裝飾器函數(shù)內(nèi)部的執(zhí)行過(guò)程是任意的,并不一定需要定義wrapper函數(shù),就像上面的代碼所示。

? ? ? ?當(dāng)然,上面的代碼僅僅是為了說(shuō)明裝飾器的原理,一般并不會(huì)這么使用。一般情況下,為了給函數(shù)添加額外的邏輯層,我們會(huì)在裝飾器函數(shù)內(nèi)定義一個(gè)wrapper函數(shù),在其內(nèi)部實(shí)現(xiàn)額外的邏輯,然后將wrapper函數(shù)返回以重新綁定到原函數(shù)。更細(xì)致的說(shuō), 裝飾器函數(shù)自己必須是個(gè)可調(diào)用的函數(shù)或者返回一個(gè)可調(diào)用函數(shù),我們說(shuō)這個(gè)可直接調(diào)用或者返回的可直接調(diào)用的函數(shù)才是真正的裝飾器,真正的裝飾器函數(shù)是單參的,參數(shù)就是被裝飾函數(shù) 。這里說(shuō)的裝飾器函數(shù)也可以是一個(gè)返回一個(gè)可調(diào)用函數(shù)的函數(shù),這樣的機(jī)制可以讓我們實(shí)現(xiàn)給裝飾器函數(shù)設(shè)定參數(shù),當(dāng)然這時(shí)的裝飾器函數(shù)實(shí)際上已經(jīng)不是真正的裝飾器了,真正的裝飾器是其返回的可調(diào)用函數(shù),對(duì)此后面我們細(xì)講。

? ? ? ?然后講一下關(guān)于被裝飾函數(shù)的參數(shù)的傳遞。如果被裝飾函數(shù)有參數(shù),嚴(yán)格的講,是如果我們調(diào)用被裝飾函數(shù)時(shí),我們給被裝飾函數(shù)傳遞了參數(shù),那么這個(gè)參數(shù)是如何傳給裝飾器函數(shù)內(nèi)部的呢?看如下代碼。

            
              def decorator_1(func):
    def wrapper(*args,**kargs):
        func()
    return wrapper

@decorator_1
def fun_1(x,y):
    print(x+y)

fun_1(3,4) # output: TypeError: fun() missing 2 required positional arguments: 'x' and 'y'


def decorator_2(func):
    def wrapper(*args,**kargs):
        func(*args,**kargs)
    return wrapper

@decorator_2
def fun_2(x,y):
    print(x+y)

fun_2(3,4) # output: 7
            
          

? ? ? ?如上代碼所示,如果我們要給被裝飾函數(shù)傳遞參數(shù),那么其就應(yīng)該按照第二種寫(xiě)法實(shí)現(xiàn)。因?yàn)閷?shí)際上,被裝飾函數(shù)的參數(shù)會(huì)自動(dòng)傳給裝飾器函數(shù)中的被返回的函數(shù),所以我們應(yīng)該給wrapper函數(shù)設(shè)定*args,**args的形式,以保證fun_2被裝飾函數(shù)的任何參數(shù)形式其都能接收,此外,wrapper函數(shù)中的func函數(shù)的參數(shù)形式也應(yīng)該同樣設(shè)定,就是為了可以接收任何函數(shù)形式,包括位置參數(shù)和關(guān)鍵字參數(shù)。

? ? ? ?最后我們將講解如何給裝飾器函數(shù)設(shè)定參數(shù)。先看參考代碼。

            
              def outer(number):
    def decorator_1(func):
        def wrapper(*args,**kargs):
            print('I love Python!')
            func(*args,**kargs)
        return wrapper
    
    def decorator_2(func):
        def wrapper(*args,**kargs):
            print('I love Pandas!')
            func(*args,**kargs)
        return wrapper
    
    if number==0:
        return decorator_1
    else:
        return decorator_2

@outer(0)
def fun1():
    print('test')

@outer(1)
def fun2():
    print('test')
            
          

? ? ? ?因?yàn)檠b飾器語(yǔ)法有如下的等價(jià)形式:

@decorator

def fun():

? ? pass

等價(jià)于

fun=decorator(fun)

即這里的decorator必須是一個(gè)可調(diào)用函數(shù),但是如果其是一個(gè)可執(zhí)行函數(shù),那么其返回的結(jié)果必須是一個(gè)可調(diào)用函數(shù),這時(shí),有如下等價(jià)關(guān)系:

@decorator(args)

def fun():

? ? pass

等價(jià)于

fun=decorator(args)(fun)

因?yàn)閐ecorator(args)本身就是一個(gè)可直接執(zhí)行的函數(shù),那么其必須返回一個(gè)可調(diào)用函數(shù),假設(shè)為deco,則上面進(jìn)一步等價(jià)為fun=deco(fun),所以這時(shí),實(shí)際上deco才是真正的裝飾器函數(shù)。

? ? ? ?下面就好理解上面的代碼了。因?yàn)閛uter(0)、outer(1)都是直接可執(zhí)行的函數(shù),其執(zhí)行后返回的結(jié)果分別為decorator_1、decorator_2,所以實(shí)際上有如下等價(jià)關(guān)系:

@outer(0)
def fun1():
? ? print('test')

@outer(1)
def fun2():
? ? print('test')

等價(jià)于

@decorator_1
def fun1():
? ? print('test')

@decorator_2
def fun2():
? ? print('test')

這樣,就不難理解,為何被裝飾函數(shù)可以作為參數(shù)傳遞給outer函數(shù)內(nèi)部的decorator函數(shù),所以,這時(shí)其實(shí)outer內(nèi)部的decorator函數(shù)才是真正的裝飾器函數(shù)。

? ? ? ?最后總結(jié)一下本文講的內(nèi)容:

1、@decorator語(yǔ)法和@deco(a,b)語(yǔ)句,相當(dāng)于直接執(zhí)行decorator(fun)和deco(a,b)(fun),并把執(zhí)行結(jié)果返回給fun;

2、被裝飾函數(shù)的參數(shù)會(huì)自行的直接傳給真正的裝飾器函數(shù)內(nèi)的被返回的可調(diào)用函數(shù),而被返回的可調(diào)用函數(shù)最好通過(guò)*args,**kargs的形式設(shè)定參數(shù),以接收任何的參數(shù)形式;

3、在理解1的基礎(chǔ)上,通過(guò)外加一層函數(shù),以實(shí)現(xiàn)給裝飾器函數(shù)自定義參數(shù)。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 日韩欧美一区二区三区不卡 | 四虎在线观看免费永久 | 国产福利视频深夜福利 | 色sese | 在线观看日韩精品 | 亚洲美女亚洲精品久久久久 | 亚洲美女操 | 久国产精品久久精品国产四虎 | 亚洲国产观看 | 香蕉蕉亚亚洲aav综合 | 国产一级特黄特色aa毛片 | 日日碰夜夜操 | 四虎影视免费永久在线观看 | 狠狠色狠狠色综合婷婷tag | 97视频观看 | 国产日韩欧美精品一区 | 国产女人精品性视频 | 亚洲欧美色综合一区二区在线 | 毛片5| 亚洲成人在线视频播放 | 欧美一级成人毛片视频 | 韩国亚洲伊人久久综合影院 | 亚洲乱码一区二区三区在线观看 | 亚洲精品视频在线 | 97午夜理伦片在线影院 | 久久精品无遮挡一级毛片 | 久久99影院网久久久久久 | 黄色在线视频观看 | 特级毛片a级毛免费播放 | 欧美一区二区三区视频在线观看 | 国产精品久久久久久久免费大片 | 国内自拍小视频 | 日本亚洲精品一区二区三区 | 国产图片综合区 | 在线观看国产福利 | 亚洲人成毛片线播放 | 婷婷色站| 成人毛片在线播放 | 午夜一级免费视频 | 四虎国产精品成人永久免费影视 | 在线不卡日韩 |