对装饰器@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
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
对装饰器@wraps的解释(一看就懂)-- 并对装饰器详解的更多相关文章
- libsvm的安装,数据格式,常见错误,grid.py参数选择,c-SVC过程,libsvm参数解释,svm训练数据,libsvm的使用详解,SVM核函数的选择
直接conda install libsvm安装的不完整,缺几个.py文件. 第一种安装方法: 下载:http://www.csie.ntu.edu.tw/~cjlin/cgi-bin/libsvm. ...
- Appium+python自动化(三十一)- 元芳,你怎么看? - 日志收集-logging(超详解)
简介 生活中的日志是记录你生活的点点滴滴,让它把你内心的世界表露出来,更好的诠释自己的内心世界,而电脑里的日志是有价值的信息宝库. 日志文件是专门用于记录系统操作事件的记录文件或文件集合,操作系统有操 ...
- RF射频传输,原理介绍,三分钟看懂!发射功率、接收灵敏度详解!
射频是什么? 官方说法:RF,Radio Frequency. (不懂的人,看了还是不懂,不过对于物联网行业的开发工程师.产品经理和项目经理,还是有需要对射频有个基础了解的.) 燚智能解读: 两个人, ...
- 怎样看K线图(实图详解)
K线图由开盘价.收盘价.最高价和最低价组成. 上面两种图叫作实体红K线和实体黑K线,实体红K线意味买力强劲,市场有强烈的做多欲望,此时可持股待涨.实体黑K线则代表市场完全进入恐惧状态,如果 ...
- python装饰器中functools.wraps的作用详解
直接上代码看效果: # 定义一个最简单的装饰器 def user_login_data(f): def wrapper(*args, **kwargs): return f(*args, **kwar ...
- 【转】详解Python的装饰器
原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...
- 详解Python的装饰器
Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...
- Python装饰器详解
python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...
- (十)装饰器模式详解(与IO不解的情缘)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. LZ到目前已经写了九个设计模 ...
随机推荐
- Vue.之.创建项目
Vue.之.创建项目 第一次使用vue的时候,在已完成node的情况下,还需要在进行安装vue. 指令:cnpm install vue-cli -g //全局安装 vue-cli 检查vu ...
- css不定高图文垂直居中的三种方法
html部分 <div class="box"> <img class="img" src="http://p2.so.qhmsg. ...
- 上传同步github
…or create a new repository on the command line echo "# testproject" >> README.md ...
- 启动Hadoop时,DataNode启动后一会儿自动消失的解决方法
查看slaver1/2的logs,发现 FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for ...
- jeecg Access restriction 问题解决
最近导入新项目,导入所有用到的jar包,发现其中一个引用报错 import com.sun.istack.internal.Nullable; 具体信息如下: Access restriction: ...
- AutoDesk产品,Maya 2018 安装,Microsoft Visual C++ 2012 安装失败,结果 = -2147024546,安装Microsoft Visual C++ 2012 Redistributable 错误0x80070005 等等
今日老弟装Maya 2018出现问题,我帮忙解决了一下问题,过程颇为曲折,记录一下,看能否帮到有类似困惑的朋友. 我和老弟的电脑牌子一样,就现在自己电脑上装了,竟然开始和他的错误是一样的!都是Micr ...
- C++通配符
#include<iostream>using namespace std;bool PathernMatch(char *pat, char *str){ char *s = NULL; ...
- iOS自动化打包上传的踩坑记
http://www.cocoachina.com/ios/20160624/16811.html 很久以前就看了很多关于iOS自动打包ipa的文章, 看着感觉很简单, 但是因为一直没有AppleDe ...
- kubernetes1.5新特性跟踪(续)
Kubernetes发布历史回顾 Kubernetes 1.0 - 2015年7月发布 Kubernetes 1.1 - 2015年11月发布 Kubernetes 1.2 - 2016年3月发布 K ...
- java memory allocation(转)
Java的运行时数据存储机制 Java程序在运行时需要为一系列的值或者对象分配内存,这些值都存在什么地方?用什么样的数据结构存储?这些数据结构有什么特点?本文试图说明此命题的皮毛之皮毛. 概念 对 ...