Python 裝飾器 wraps作用 使用記錄

2021-09-17 21:16:35 字數 3650 閱讀 8795

def

is_login

(func)

:def

foo(

*args,

**kwargs)

:return func(

*args,

**kwargs)

return foo

deftest()

:print

('我是:'

,test.__name__)

@is_login

deftest1()

:print

('我是:'

,test1.__name__)

@is_login

deftest2()

:print

('我是:'

,test2.__name__)

test(

)test1(

)test2(

)>>

>>

我是: test

我是: foo

我是: foo

可以發現函式的函式名即 __name__已被裝飾器改變2.那我們來增加@wraps

from functools import wraps

defis_login

(func)

: @wraps(func)

deffoo

(*args,

**kwargs)

:return func(

*args,

**kwargs)

return foo

deftest()

:print

('我是:'

,test.__name__)

@is_login

deftest1()

:print

('我是:'

,test1.__name__)

@is_login

deftest2()

:print

('我是:'

,test2.__name__)

test(

)test1(

)test2(

)>>

>>

我是: test

我是: test1

我是: test2

可以看見@wraps可以保證裝飾器修飾的函式的__name__的值保持不變

以時間裝飾器為例,進行優化

from functools import wraps

# 對函式的裝飾器, 對類func最好為cls

defdecorate

(func)

: @wraps(func)

# 增添或修改功能的函式

def(

*args,

**kwargs)

:# 執行被裝飾的函式

result = func(

*args,

**kwargs)

# 返回結果

return result

# 返回內層函式

普通–時間裝飾器

from functools import wraps

import time

from random import randint

defuse_time

(func)

: @wraps(func)

def(

*args,

**kwargs)

: st_time = time.time(

) result = func(

*args,

**kwargs)

end_time = time.time(

)print

(f'函式use_time:s')

@use_time

deffoo()

: time.sleep(randint(1,

3))for _ in

range(3

):foo(

)#輸出

>>

>>

foo函式use_time:

1.0007495880126953s

foo函式use_time:

3.0018675327301025s

foo函式use_time:

3.0030477046966553s

下面對改裝飾器進行優化(解耦)
# 在增加一層函式

from functools import wraps

import time

from random import randint

defrecord

(output)

:def

use_time

(func)

: @wraps(func)

def(

*args,

**kwargs)

: st_time = time.time(

) result = func(

*args,

**kwargs)

end_time = time.time(

)# print(f'函式use_time:s')

output(func.__name__, end_time-st_time)

return use_time

# 改裝飾器的結果就可以自定義了,下面以print函式為例

@record(

print

)def

foo():

time.sleep(randint(2,

5))for _ in

range(3

):foo(

)>>

>>

foo 3.000645875930786

foo 4.003818988800049

foo 2.0020666122436523

結果輸出日誌

def

write_log

(name,content)

:with

open

('./time.log'

,'a'

)as f:

f.write(f'耗時:\r\n'

)# \r\n 換行

# 只需要將裝飾器改為@record(write_log)

@record(write_log)

deffoo()

: time.sleep(randint(2,

5))for _ in

range(3

):foo(

)

效果如下

Python裝飾器中 wraps作用

裝飾器的作用 在不改變原有功能 的基礎上,新增額外的功能,如使用者驗證等。wraps view func 的作用 不改變使用裝飾器原有函式的結構 如name,doc 不使用 wraps裝飾器時候,看看 name doc 輸出的內容是什麼def decorator func this is decor...

python筆記36 裝飾器之wraps

前面一篇對python裝飾器有了初步的了解了,但是還不夠完美,領導看了後又提出了新的需求,希望執行的日誌能顯示出具體執行的哪個函式。name 用於獲取函式的名稱,doc 用於獲取函式的docstring內容 函式的注釋 import time def func a a func a hello pr...

wraps裝飾器的使用

使用functools模組提供的wraps裝飾器可以避免被裝飾的函式的特殊屬性被更改,如函式名稱 name 被更改。如果不使用該裝飾器,則會導致函式名稱被替換,從而導致端點 端點的預設值是函式名 出錯。不使用wraps裝飾器時 def test func def decorated function...