對裝飾器@wraps的解釋(一看就懂)-- 並對裝飾器詳解


1. 先看一段代碼

def is_login(func): def foo(*args,**kwargs): return func(*args,**kwargs) return foo def 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 wraps def is_login(func):  @wraps(func) def foo(*args,**kwargs): return func(*args,**kwargs) return foo def 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 randint 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') 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 randint def 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 wrapper 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'{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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM