python装饰器是高阶函数 ,但装饰器是对传入函数的功能的增强,用于拓展原函数功能的函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
装饰器语法糖:
使用:@logger,这就是装饰器语法
例:记录函数的运行时常
python的文档字符串:
在函数语句块的第一行,习惯是多行的文本,所以多使用三引号,惯例是首字母大写,第一行写概述,空一行,第三行写详细描述,可以使用特殊属性__doc__访问这个文档
例:
装饰器的副作用:
原函数对象的属性都被替换了,如何解决?
提供一个函数,将原函数的属性该换为自己原来的属性,用带参装饰器实现
带参装饰器:
例:获取函数的执行时长,对时长超过阈值的函数记录一下,将记录的功能提取出来,这样可以通过外部提供的函数来灵活的控制输出
functools模块
functools.update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS,updated=WRAPPER_UPDATES)
类似copy_properties的功能,wrapper 为copy_properties的dst,wrapped为copy_properties的src
元组WRAPPER_ASSIGNMENTS中是要被覆盖的属性:‘__module__':模块名,’__name__':名称,'__qualname__':限定名,'__doc__':文档,'__annotations__':参数注解;
元组WRAPPER_UPDATES中是要被更新的属性,__dict__属性字典,增加一个__wrapped__属性,保留着wrapped函数
改写上面的函数:
@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
类似copy_properties的功能,wrapped被包装函数,为copy_properties的src
元组WRAPPER_ASSIGNMENTS中是要被覆盖的属性:‘__module__':模块名,’__name__':名称,'__qualname__':限定名,'__doc__':文档,'__annotations__':参数注解;
元组WRAPPER_UPDATES中是要被更新的属性,__dict__属性字典,增加一个__wrapped__属性,保留着wrapped函数
改写上面的函数: