通俗易懂的理解 python 裝飾器

2021-10-03 17:30:17 字數 3910 閱讀 1919

舉例

def

play()

:print

("小王在玩遊戲"

) sleep(3)

print

("遊戲結束"

)

我想計算play花費的時間

def

play()

: start = time.time(

)print

("小王在玩遊戲"

) sleep(3)

print

("遊戲結束"

) end = time.time(

)print

("用時"

.format

(end - start)

)

如果我還想計算其他類似函式的時間怎麼辦?

我可以把計算函式時間封裝成乙個函式,解決冗餘問題

def

cal_time

(func)

: start = time.time(

) func(

) end = time.time(

)print

("用時"

.format

(end-start)

)

這樣解決了冗餘問題,但是有個新的問題,我想計算時間就必須呼叫cal_time方法

有沒有方法可以仍然呼叫play等計算時間需求本身的函式而又可以解決重複冗餘問題呢

這就是下面的裝飾器

def

cal_time

(func)

:def()

: start = time.time(

) func(

) end = time.time(

)print

("用時"

.format

(end - start)

)@cal_time

defplay()

:print

("小王在玩遊戲"

) sleep(3)

print

("遊戲結束"

)if __name__ ==

'__main__'

: play(

)

裝飾器通過定義內建函式,把需要裝飾的函式(play)和一些自由變數(start,end等)繫結在一起,從而實現解決冗餘,同時儲存原函式呼叫方法

那麼怎麼傳遞引數呢?

def

cal_time

(func)

:def

(*args)

: start = time.time(

) func(

*args)

end = time.time(

)print

("用時"

.format

(end - start)

)@cal_time

defplay

(game)

:print

("小王在玩遊戲 %s"

% game)

sleep(3)

print

("遊戲結束"

)if __name__ ==

'__main__'

: play(

"lol"

)

下面是帶有 **kwargs引數的裝飾器

def

cal_time

(func)

:def

(*args,

**kwargs)

: start = time.time(

) func(

*args,

**kwargs)

end = time.time(

)print

("用時"

.format

(end - start)

)@cal_time

defplay

(game,name,t)

:print

("%s 在玩遊戲 %s"

%(name,game)

) sleep(t)

print

("遊戲結束"

)if __name__ ==

'__main__'

: play(

"lol"

,"小虎"

,t=5

)

注意:

def

cal_time

(func)

:def

(*args,

**kwargs)

: start = time.time(

) res = func(

*args,

**kwargs)

end = time.time(

)print

("用時"

.format

(end - start)

)return res # 返回值

@cal_time

defplay

(game, name, t)

:print

("%s 在玩遊戲 %s"

%(name, game)

) sleep(t)

print

("遊戲結束"

)return name # 返回值

if __name__ ==

'__main__'

: username = play(

"lol"

,"小虎"

, t=5)

print

(username)

下面是另乙個例子

import functools

deflog

(func)

: @functools.wraps(func)

def(

*args,

**kwargs)

:print

('call %s():'

% func.__name__)

print

('args = {}'

.format

(*args)

)return func(

*args,

**kwargs)

@log

deftest

(p):

print

(test.__name__ +

" param: "

+ p)

if __name__ ==

'__main__'

: test(

"i'm a param"

)

裝飾器在使用時,用了@語法,讓人有些困擾。其實,裝飾器只是個方法,與下面的呼叫方式沒有區別:

def

test

(p):

print

(test.__name__ +

" param: "

+ p)

"i'm a param"

)

參考

python關鍵字引數

python裝飾器

通俗易懂 理解「委託」

委託的意義在於實現多型 在於讓物件能夠在程式執行時滿足外界對其的改變。1 乙個物件屬性 動作,如果在編譯時就能確定,可以在這個物件的類裡面來實現。2 乙個物件的屬性 動作,如果在執行時才能確定,則只能通過這個物件的委託來實現。換句話說 類,滿足編譯時對物件的設定和要求。委託,用於滿足執行時對物件的設...

通俗易懂 Python閉包 裝飾器

參考的資料 舉乙個例子 def secondflood msg 你好 defthirdflood print msg secondflood 結果如下 是呼叫不到內嵌在裡面的函式的 使用如下方式 def secondflood msg 你好 defthirdflood print msg retur...

通俗易懂的裝飾器模式

裝飾器模式 decorator pattern 允許向乙個現有的物件新增新的功能,同時又不改變其結構。這種型別的設計模式屬於結構型模式,它是作為現有的類的乙個包裝。這種模式建立了乙個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。意圖 動態地給乙個物件新增一些額外的職責...