
python学习笔记3.4-函数装饰器
发布日期:2021-05-15 15:40:51
浏览次数:19
分类:精选文章
本文共 2402 字,大约阅读时间需要 8 分钟。
软件开发过程中,重复性工作是 Avoid 的关键技能。在 Python 中,当需要创建高度重复的代码时,元 Programing 是最常采用的解决方案。简单而言,元编程的核心目标就是通过创建函数和类来操纵代码,实现行为的生成、修改和包装。Python 提供了多种元编程技巧,如装饰器、类装饰器、元类,以及用途广泛的主题工具(如对象签名、exec()用于执行代码以及检查函数和类的内部结构)。
1 装饰器
1.1 用装饰器给函数添加一个包装
装饰器的本质是一个能够接收并返回新函数的函数。它可以用来为函数添加额外处理,例如记录日志、计时统计等。在事实上,一个非常常见的应用场景是记录函数的运行时间。
简单的示例:
def CutDown(n): import time start = time.time() while n > 0: n -= 1 end = time.time() print(end - start)CutDown(10000000)
输出结果:
1.1250569820404053秒
引入装饰器的方法:
def GetRunTime(func): import time from functools import wraps @wraps(func) def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(func.__name__, end - start) return result return wrapper@GetRunTimedef cutdown(n): while n > 0: n -= 1cutdown(10000000)
输出结果:
cutdown 1.1274616718292236秒
用这种方法的优势在于,只需为需要记录运行时间的函数添加装饰器即可,极大地简化了调试过程。
1.2 运用装饰器时保存函数的元数据
未使用 @wraps(func)
detectives 的话,被装饰函数会失去元数据,如函数名、文档字符串、注解以及调用签名。
未使用 wraps
的示例:
def GetRunTime(func): import time def wrapper(*args, **kwargs): """参数描述:args、kwargs;返回:函数结果""" start = time.time() result = func(*args, **kwargs) end = time.time() print(func.__name__, end - start) return result return wrapper@GetRunTimedef cutdown(n): """参数描述:n;返回:None""" while n > 0: n -= 1cutdown(10000000)print(cutdown.__name__)print(cutdown.__doc__)
注意:
打印输出结果为:
wrapper 1.4844520092010498秒wrapper :参数描述:args;返回:None
使用 @wraps(func)
后的示例:
from functools import wrapsdef GetRunTime(func): import time @wraps(func) def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(func.__name__, end - start) return result return wrapper@GetRunTimedef cutdown(n): """参数描述:n;返回:None""" while n > 0: n -= 1print(cutdown.__name__) # 输出:cutdownprint(cutdown.__doc__) # 输出:参数描述:n;返回:None
输出结果示例:
cutdown 1.193265676498413秒cutdown :参数描述:n;返回:None
可以看出,使用 @wraps(func)
后,函数的元数据完整保留。
1.3 对装饰器进行解包
可以通过 wrapped
属性解包装后的函数。例如:
@GetRunTimedef cutdown(n): """参数描述:n;返回:None""" print('cutdown is running') while n > 0: n -= 1# 使用 wrapped 属性调用原函数print(cutdown.__wrapped__(10000000))
输出结果:
cutoff is running
这种方法特别有用,当函数有多个装饰器时,可以直接访问被装饰后的函数。
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月22日 02时52分52秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Java位运算,负数的二进制表示形式,int类型最大值为什么是2的31次方-1
2019-03-12
JQuery--手风琴,留言板
2019-03-12
MFC 自定义消息发送字符串
2019-03-12
goahead 下goaction测试与搭建
2019-03-12
Linux操作系统的安装与使用
2019-03-12
ajax请求出现/[object%20Object]错误的解决办法
2019-03-12
流体运动估计光流算法研究
2019-03-12
如何转载博客
2019-03-12
C++ 继承 详解
2019-03-12
OSPF多区域
2019-03-12
Grafana导入 Promethus node模板
2019-03-12
如何提高SQL查询的效率?
2019-03-12
Docker入门之-镜像(二)
2019-03-12
数据结构——链表(3)
2019-03-12
socket模块和粘包现象
2019-03-12
Python学习--模块
2019-03-12
去了解拉绳位移编码器的影响因素
2019-03-12
影响拉线位移传感器精度的原因有哪些?
2019-03-12
无法初始化Winsock2.2处理
2019-03-12
Horizon Cloud之UAG访问异常
2019-03-12