对装饰器@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到目前已经写了九个设计模 ...
随机推荐
- 常见任务&基本工具 1 软件包管理
打包系统主要有两个阵营 包文件的简介 Package files are created by a person known as a package maintainer, often (but n ...
- 洛谷P1774 最接近神的人_NOI导刊2010提高(02) [2017年6月计划 线段树03]
P1774 最接近神的人_NOI导刊2010提高(02) 题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门 ...
- html 遮罩层以及弹出框的制作
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Windows Phpstrom svn 配置
网上百度找到的解决方案行不通,就是下图两项都不选中.临时是可以的,但是到了第二天,又不行了. 以下是自己瞎弄的,居然可以了. 第一步:安装TortoiseSVN 1.8.* ,注意安装选项要选上com ...
- SpringMVC代码复制版
Lib目录 Java目录 HelloController文件代码 import org.springframework.web.servlet.ModelAndView; import org.spr ...
- 使用nuxt.js官方脚手架构建koa2的es6编译问题
最近在学用nuxt集成koa2做vue后台,发现官方自带脚手架搭建的koa2使用的仍是es5语法,如果想用es6怎么办呢? 这是由于自带脚手架在构建koa2时默认的nodemon是没有使用babel编 ...
- mysql各个引擎区别
1.如果你有一个 MyISAM 数据表包含着 FULLTEXT 或 SPATIAL 索引,你将不能把它转换为使用 另一种引擎,因为只有 MyISAM 支持这两种索引. 2. 如果你有一个数据表包含着一 ...
- 使用cnpm真的会有诡异的Bug
前端网页居然会出现堆栈溢出,然后网页崩溃,退出的问题. 出现这个Bug的时候,我非常的怀疑我自己的一些操作能力,比如,git的操作. 毕竟我是本地代码然后拉取远程分支,还会暂存自己的代码,然后暂存区代 ...
- PHP获取用户客户端真实IP的解决方案是怎样呢?
function getIp(){if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIE ...
- Spark-day01
Spark初始 什么是Spark Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎.Spark是UC Berkeley AMP lab (加州大学伯克利分校的AMP实验室) ...