日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python编写装饰器_我也来写一下python装饰器

發(fā)布時(shí)間:2023/12/20 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python编写装饰器_我也来写一下python装饰器 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

有借用,但原文出處已經(jīng)找不到了,根據(jù)筆記分享一下解釋器的基礎(chǔ)。

下面的代碼表示,等待兩秒鐘,輸出‘test is running'。

現(xiàn)在要求增加統(tǒng)計(jì)程序運(yùn)行時(shí)間的功能。

等待兩秒鐘,輸出‘test is running',現(xiàn)要求增加統(tǒng)計(jì)程序運(yùn)行時(shí)間的功能。

import time

def test():

time.sleep(2)

print('test is running!')

test()

學(xué)習(xí)先問(wèn)為什么,有什么用,學(xué)基礎(chǔ)的時(shí)候有時(shí)不理解為什么簡(jiǎn)單的事情要搞那么復(fù)雜,而對(duì)應(yīng)的實(shí)際應(yīng)用時(shí),往往“這個(gè)復(fù)雜方法有很多優(yōu)點(diǎn)和簡(jiǎn)化了很多事情”。學(xué)基礎(chǔ)時(shí)用簡(jiǎn)單的例子,只是為了講明知識(shí)點(diǎn),而不要去關(guān)注例子實(shí)現(xiàn)的什么功能,這個(gè)功能當(dāng)然是個(gè)‘屁’了。

那么,裝飾器的實(shí)際應(yīng)用場(chǎng)景:程序已上線或已使用,但需要增加新功能,修改原函數(shù)不合理也不科學(xué)(這里真的包含了很多背景聲音),就要求:

(1)不能修改原功能函數(shù)的代碼。例子中的功能是非常簡(jiǎn)單的,要實(shí)現(xiàn)當(dāng)然是直接修改,但現(xiàn)實(shí)中一個(gè)功能的實(shí)現(xiàn)是非常復(fù)雜的代碼,直接修改是不合理不科學(xué)的。

(2)不能修改原函數(shù)的調(diào)用方式。在符合第一條的情況下,調(diào)用時(shí)仍然是用test(),即老方法能實(shí)現(xiàn)新功能。現(xiàn)實(shí)中后面程序在反復(fù)用test(),就是要完全不動(dòng)老代碼的基礎(chǔ)上,增加一個(gè)’裝飾器‘更新整個(gè)程序。

(3)上述說(shuō)的老方法是表面上的,這就是裝飾器介入的作用。

好,以下開(kāi)始改造,用試錯(cuò)的方法解釋裝飾器的實(shí)現(xiàn)過(guò)程和原理。

滿足條件(1)可以增加代碼如下:

def deco(func):

start=time.time()

func()

stop=time.time()

print(stop-start)

deco(test)

#把老代碼里的test函數(shù)作為參數(shù)傳遞給新函數(shù)

#(因?yàn)槭窃黾有鹿δ?#xff0c;老功能還是要的,所以新代碼里肯定要引用老代碼的功能,就采取了這種方法)

看上去新功能就實(shí)現(xiàn)了,但可以看到調(diào)用方式變?yōu)榱薲eco(test),即違背了條件(2),以前程序里可能反復(fù)調(diào)用了test(),都要改成deco(test),不科學(xué)。

同時(shí)滿足條件(2),再改:

思路:產(chǎn)生一個(gè)新函數(shù),重新賦值給test,test=某函數(shù),那么后面反復(fù)調(diào)用的test()就被實(shí)質(zhì)上改過(guò)來(lái)了,實(shí)現(xiàn)功能。

#試一下:

test=deco(test) #計(jì)算右邊的,是一個(gè)兩行字符串,賦值給test根本不是一個(gè)函數(shù)。

test() #因此跳錯(cuò)誤碼

再試一下:

增加:return func

然后:

test=deco(test)

test()

代碼正常運(yùn)行,但因?yàn)閞eturn func的縮進(jìn)和其他代碼是同級(jí)的,所以deco(test)這步已經(jīng)把新功能給實(shí)現(xiàn)了,又返回了一次test(),結(jié)果重復(fù)。

把下面完整的代碼去試一下,出現(xiàn)了兩次test is running ,不合格。

import time

def test():

time.sleep(2)

print('test is running!')

def deco(func):

start=time.time()

func()

stop=time.time()

print(stop-start)

return func

test=deco(test)

test()

思路沒(méi)有錯(cuò),上述這里return一個(gè)函數(shù)的思考過(guò)程也是對(duì)的,只是返回的方式不對(duì),應(yīng)當(dāng)使用’嵌套函數(shù)‘。

def timer(func):

def deco():

start=time.time()

func()

stop=time.time()

print(stop-start)

return deco

#把deco()嵌套在timer(func)里,返回一個(gè)deco()函數(shù)的函數(shù)名deco;

#調(diào)用timer(func)時(shí),deco()里面的過(guò)程代碼類(lèi)似于沒(méi)有執(zhí)行的,

#被打包成了一個(gè)函數(shù),執(zhí)行的只是return了這個(gè)函數(shù)的函數(shù)名。

test=timer(test)

#右邊代碼返回的是一個(gè)deco()的函數(shù)名deco,deco()打包了作為被參數(shù)傳入的原test()里的功能,

#同時(shí)增加了新功能。

test()

#符合(2)要求,沒(méi)有改變調(diào)用方法,但實(shí)質(zhì)上這句調(diào)用的已經(jīng)是deco()了。

#頂格代碼是不能調(diào)用經(jīng)過(guò)了二次縮進(jìn)的嵌套函數(shù)的,

#但這里用了deco()用了return,成了閉包函數(shù),就可以被調(diào)用了。

至此,本質(zhì)上是修改了調(diào)用函數(shù),但在表面上并未修改調(diào)用方式,而且實(shí)現(xiàn)了附加功能,需求實(shí)現(xiàn)。

真正的裝飾器:語(yǔ)法糖

在原test()的上一行加上@timer,刪除test=timer(test).

而且要把新增的函數(shù)寫(xiě)在原函數(shù)的上面

最后代碼

import time

def timer(func):

print(func.__name__) #看看打印出來(lái)的是什么

def deco():

start=time.time()

func()

stop=time.time()

print(stop-start)

return deco

@timer

def test():

time.sleep(2)

print('test is running')

#test=timer(test)這句不用了,注釋掉

test()

過(guò)程比較啰嗦,但每一步都看下來(lái)后,裝飾 器的原理就知道了,涉及到有參數(shù)的時(shí)候,再另外理解了。

總結(jié)

以上是生活随笔為你收集整理的python编写装饰器_我也来写一下python装饰器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。