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...