对装饰器@wraps的解释(一看就懂)-- 并对装饰器详解
生活随笔
收集整理的這篇文章主要介紹了
对装饰器@wraps的解释(一看就懂)-- 并对装饰器详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1. 先看一段代碼
def is_login(func):def foo(*args,**kwargs):return func(*args,**kwargs)return foodef test():print('我是:',test.__name__)@is_login
def test1():print('我是:',test1.__name__)
@is_login
def test2():print('我是:',test2.__name__)test()
test1()
test2()>>>>我是: test
我是: foo
我是: foo
可以發現函數的函數名即 name已被裝飾器改變
2.那我們來增加@wraps
from functools import wrapsdef is_login(func):@wraps(func)def foo(*args,**kwargs):return func(*args,**kwargs)return foodef test():print('我是:',test.__name__)@is_login
def test1():print('我是:',test1.__name__)
@is_login
def test2():print('我是:',test2.__name__)test()
test1()
test2()>>>>
我是: test
我是: test1
我是: test2
結論:
可以看見@wraps可以保證裝飾器修飾的函數的name的值保持不變
補充:裝飾的優化
以時間裝飾器為例,進行優化
- 裝飾器的統一模板
from functools import wraps
# 對函數的裝飾器, 對類func最好為cls
def decorate(func):@wraps(func)# 增添或修改功能的函數def wrapper(*args,**kwargs):# 執行被裝飾的函數result = func(*args,**kwargs) # 返回結果return result# 返回內層函數return wrapper
普通--時間裝飾器
from functools import wraps
import time
from random import randintdef use_time(func):@wraps(func)def wrapper(*args,**kwargs):st_time = time.time()result = func(*args,**kwargs)end_time = time.time()print(f'{func.__name__}函數use_time:{end_time-st_time}s')return wrapper@use_time
def foo():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 randintdef record(output):def use_time(func):@wraps(func)def wrapper(*args,**kwargs):st_time = time.time()result = func(*args,**kwargs)end_time = time.time()
# print(f'{func.__name__}函數use_time:{end_time-st_time}s')output(func.__name__, end_time-st_time)return wrapperreturn 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'{name}耗時:{content}\r\n') # \r\n 換行# 只需要將裝飾器改為@record(write_log)
@record(write_log)
def foo():time.sleep(randint(2,5))for _ in range(3):foo()
效果如下
效果如圖作者:憧憬001
鏈接:https://www.jianshu.com/p/5df1769e562e
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。
總結
以上是生活随笔為你收集整理的对装饰器@wraps的解释(一看就懂)-- 并对装饰器详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Bert源码阅读
- 下一篇: 时间统计%time和%timeit_py