python装饰器原理-python 中的装饰器及其原理
装饰器模式
此前的文章中我们介绍过装饰器模式:
装饰器模式中具体的 Decorator 实现类通过将对组建的请求转发给被装饰的对象,并在转发前后执行一些额外的动作来修改原有的部分行为,实现增强 Component 对象中被请求方法的目的
装饰器模式是一种十分灵活的,可以动态添加和分离额外操作的设计模式,python 中的装饰器正是因为这个模式而得名,也是实现这个设计模式的得力工具
python 装饰器实现自动监控
装饰器模式的一个典型的应用场景就是对所有需要被监控的方法实现无差别的自动日志打印和监控上报的一些统计功能
下面的例子展示了函数执行时间的自动打印:
import time
import functiontools
import logging
def clock(func):
@functools.wraps(func)
def clocked(*args):
t0 = time.perf_counter()
result = func(*args)
elapsed = time.perf_counter() - t0
name = func.__name__
arg_str = ', '.join(repr(arg) for arg in args)
logging.info('[%0.8fs] %s(%s) -> %r' % (elapsed, name, arg_str, result))
return result
return clocked
上面的例子中,通过装饰器与闭包,实现了对 func 的增强,通过装饰器 clock,自动在 log 中打印了方法的执行时间
我们定义函数:
@clock
def snooze(seconds):
time.sleep(seconds)
return seconds
if __name__ == '__main__':
print(snooze(.123))
打印出了:[0.12405610s] snooze(.123) -> 0.123
0.123
functools.wraps
functools.wraps 是标准库中的一个装饰器,他把相关的属性从 func 复制到 clocked 中,从而让装饰器的外部表现与被装饰函数的表现林亮一直
监控优化 -- 增加参数
很多时候,我们需要在装饰器上传递一些参数,以实现不同场景的定制化需求,例如有些时候我们希望打印出全部参数、返回值,有些时候需要在发生异常时隐藏异常,返回预设的默认值等
了解了装饰器的原理以后,包含参数的装饰器就很容易写出来,事实上,无论嵌套多少层,只要记得开始的时候我们提到的装饰器的原理,就都不难理解了
import inspect
import logging
import time
import uuid
from functools import wraps
def report(project=None, type=None, name=None, raise_exception=True, result=None, paramslog=False, returnlog=False):
def decorator(func):
@wraps(func)
def wrapper(*arg, **kvargs):
cattype = type
if cattype is None:
cattype = inspect.getfile(func)
if project is not None:
cattype = '[:: ' + project + ' ::] ' + cattype
catname = name if name is not None else func.__name__
randid = str(uuid.uuid1())
if paramslog:
logging.info('<%s::%s> [%s] PARAMS: %r; %r' % (cattype, catname, randid, arg, kvargs))
try:
t0 = time.perf_counter()
res = func(*arg, **kvargs)
elapsed = time.perf_counter() - t0
if returnlog:
logging.info('<%s::%s> [%s;%0.8fs] RESULT: %r' % (cattype, catname, randid, elapsed, res))
return res
except Exception as e:
logging.error('<%s::%s> [%s] ERROR: %r' % (cattype, catname, randid, e), exc_info=True)
if raise_exception:
raise e
else:
return result
return wrapper
return decorator
python装饰器原理-python 中的装饰器及其原理相关推荐
- webpack 中的加载器简介||webpack 中加载器的基本使用——1. 打包处理 css 文件 2. 打包处理 less 文件 3.打包处理 scss 文件
webpack 中的加载器 1. 通过 loader 打包非 js 模块 在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块,其他非 .js 后缀名结尾的模块, webpa ...
- java8收集器,Java 8中的收集器collectionAndThen()方法
collectingAndThen()Java Collectors类中的方法使Collector适应于执行其他完成转换.它返回执行下游收集器动作的收集器,然后执行附加的结束步骤. 语法如下.stat ...
- java web 过滤器 拦截器 监听器_Java中的拦截器和过滤器,可不是同一个东西
过滤器(Filter) 过滤器就如上面的水质过滤器一样,把管道中的水进行一遍过滤再使用.过滤器基于filter接口中的doFilter回调函数,主要的用途是设置字符集.控制权限.控制转向.做一些业务逻 ...
- java 反复器_java集合类中的枚举器(反复器)
在任何集合类中,必须通过某种方法在其中置入对象,再用另一种方法从中取得对象.毕竟,容纳各种各样的对象正是集合的首要任务.在Vector中,addElement()便是我们插入对象采用的方法,而elem ...
- android节操播放器回调,Android中节操播放器JieCaoVideoPlayer使用
##效果 ##使用 即便是自定义UI,或者对Library有过修改,也是这五步骤来使用播放器. ####1.添加类库 compile 'cn.jzvd:jiaozivideoplayer:6.0.0' ...
- java web 嵌套播放器_网页中嵌套视频播放器
刚做完一个项目,其中有个视频播放的,其实网上的代码都没有错,但感觉不详细,特别是播放文件的路径,有本地的,有当前项目中的,有网络上的,网上很多,但没有一个说明是哪个路径,这里,经过本人测试,不多说了, ...
- 计算机晶体管怎么工作原理,CPU中的晶体管的工作原理?
描述 CPU的产生 在了解CPU工作原理之前,我们先简单谈谈CPU是如何生产出来的.CPU是在特别纯净的硅材料上制造的.一个CPU芯片包含上百万个精巧的晶体管.人们在一块指甲盖大小的硅片上,用化学的方 ...
- impinj固定式阅读器数据解析中Rfid筛选器实现
在做物联网仓库管理中用到RFID标签进行盘点和出库扫描检查,其中在仓库门口的impinj固定式阅读器对进出的货物进行检测,在读取rfid时候需要对epc标签进行过滤,实现2个过滤器,第一个是正则过滤, ...
- android调用文件管理器回调,Android中调用系统管理器选择文件并返回绝对路径
选择文件的时候,如果使用的是第三方软件,一般是直接返回绝对路径的Uri,如果是系统的,则会返回媒体库的xxxx,所以单纯一种方式选择文件,很可能拿到的绝对路径是错的或者是空的,所以需要做几种处理,这里 ...
- matlab图像读取原理,matlab中imread读入图像的原理
imread的使用方法是: I=imread('C:\XXXX\XXXX.jpg'); I = imread('E:\2012\The standard image\Lena.bmp'); I1 = ...
最新文章
- android:themes.xml
- 阿里专家讲中台:技术中台-分布式架构在蚂蚁金服的实践
- 如何下载github项目中的某一部分
- Hive安装问题简述
- 从零开始学习jQuery (九) jQuery工具函数
- list中抽出某一个字段的值_使用LINQ获取List列表中的某个字段值
- 计算机网络 | IP协议相关技术与网络总结 :DNS、ICMP、DHCP、NAT/NAPT、通信流程
- 服务器日志显示意外关闭,服务器事件日志
- 序列化、模块 day21
- 【原创】开源Math.NET基础数学类库使用(04)C#解析Matrix Marke数据格式
- Linux查看和修改IP地址
- Bootstrap 模态框(Modal)
- php v9 用于静态页查询登陆状态以及用户信息的ajax接口,phpcms V9如何判断用户是否登录以及登陆后的标签写法问题 - 小众知识...
- springmvc和encache集成
- 汽车服务架构(SOA)开发设计
- html5 uc qq,(进阶版)手机浏览器用户体验报告:UC、QQ、360,到底哪个好?
- 计算机上的程序全是应用程序,手把手教你不是有效的 win32 应用程序怎么解决...
- 如何查看Steam的17位Id
- Profile多环境支持
- 【建议收藏】20个Python非常有用的单行代码