python中的装饰器
来源:互联网 发布:天刀神威女捏脸数据 编辑:程序博客网 时间:2024/05/16 17:12
Python中的装饰器可以很方便的对已有的函数进行改写或者优化,从某种程度上可以将函数看成类,装饰器的作用就是类继承的过程。
def log(func): def wrapper(*arg,**kw): print('call %s' % func.__name__) return func(*arg,**kw) return wrapper@logdef now(): print('2017-1-7')now()
运行的结果是:
call now2017-1-7
代码中的@
语法相当于now=log(now)
。我们可以将上面的代码写成下面的形式:
def log(func): def wrapper(*arg,**kw): print('call %s' % func.__name__) return func(*arg,**kw) return wrapperdef now(): print('2017-1-7')log(now)()
结果依然是:
call now2017-1-7
从上面两段代码可以看出@xxx
的作用等价于now=xxx(now)
,也就是log
是一个将紧跟他下面的函数作为参数的函数。无论函数xxx
里有多少层函数,跟在@后面的函数或其所指向的函数必须是以函数作为参数的。我们来看下面一段代码:
def log(text): if isinstance(text,str): def decorator(func): def wrapper(*args, **kw): print('%s %s():' % (text, func.__name__)) return func(*args, **kw) return wrapper return decorator else: def wrapper(*args, **kw): print('call %s()' % text.__name__) return text(*args, **kw) return wrapper @logdef now1(): print('2017-1-7')@log('excute')def now2(): print('2017-1-7')now1()now2()
运行结果如下:
call now()2017-1-7excute now():2017-1-7
上面的这段代码中的装饰器,除了正常的功能外,还可以加参数,这是为什么呢?在函数log
中,先判断的是参数text
的类型,先不论text
是那种类型,函数log或其所指向的函数必须都是以函数作为参数的。@log
的作用等价于now1=log(now1)
,now1
是函数类型,不是字符串类型,所以执行的是这段代码:
def wrapper(*args, **kw): print('call %s()' % text.__name__) return text(*args, **kw) return wrapper
在@xxx
中xxx
就是一个函数,因此@log('excute')
中log('excute')
就是一个函数,所以log('excute')
的作用等价于now2=log('excute')(now2)
。但是,'excute'
先传进去的所以经判断执行的是这段代码:
def decorator(func): def wrapper(*args, **kw): print('%s %s():' % (text, func.__name__)) return func(*args, **kw) return wrapper return decorator
在这还有最后一个问题就是now
的__name__
属性会变成wrapper
,还是因为now2=log('excute')(now2)
。log('excute')(now2)
指向的函数就是wrapper
,因此完整的代码就是:
import functoolsdef log(text): if isinstance(text,str): def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): print('%s %s():' % (text, func.__name__)) return func(*args, **kw) return wrapper return decorator else: @functools.wraps(text) def wrapper(*args, **kw): print('call %s()' % text.__name__) return text(*args, **kw) return wrapper @logdef now1(): print('2017-1-7')@log('excute')def now2(): print('2017-1-7')now1()now2()
@functools.wraps(func)
的作用就是wrapper.__name__ = func.__name__
。
0 0
- Python中的装饰器
- python中的装饰器
- python中的装饰器
- python中的装饰器
- Python中的装饰器
- Python中的装饰器
- python中的装饰器
- python中的装饰器
- python中的装饰器
- Python中的装饰器
- Python中的装饰器
- python中的装饰器
- Python中的装饰器
- Python中的装饰器
- Python 中的装饰器
- python中的装饰器
- Python中的装饰器
- python中的装饰器
- c控制语句:循环(2)
- java 二进制兼容性概述
- 计算机网络重要知识点
- 详解Oracle partition分区表
- 简洁精美源于分析透彻,构思明确、求精,逻辑练达。(7)
- python中的装饰器
- CSS3--文本效果
- Apache虚拟主机配置
- 深度学习Caffe实战(9)Windows 平台caffe用MATLAB接口实现训练网络和测试
- 简洁精美源于分析透彻,构思明确、求精,逻辑练达。(8)
- Gearman——分布式任务分发框架
- Windows 编程中用Service开启一个外部进程的两种语言实现方式(C++,C#)。
- springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)
- 指针(二)