对装饰器@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