python 高阶函数:Decorato
装饰器:原函数基础 ------> 动态添加功能
一、不带参数的decorator
#decorator封装
def log(func):
def wrapper(*args, **kw):
print 'call %s():' %func.__name__
return func(*args, **kw)
return wrapper
#此函数一定要放在 def log(func): 之后
@log
def now():
print "haha"
now()
log(now())
print "now_name:%s"%now.__name__
简单的图解:(待以后深入理解后再详细补)
二、带参数的docurator
#!/usr/bin/python
#docurator封装
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
@log('execute')
def now():
print "haha"
print "now_name:%s"%now.__name__
now()
print log('execute')
print log(now)
print log('execute')(now)
三、完整的decorator的写法:Python内置的functools.wraps
import functools #导入functools模块
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
@log('execute')
def now():
print "haha"
print "now_name:%s"%now.__name__
now()
print log('execute')
print log(now)
print log('execute')(now)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
日期:2018/8/18
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
补充:
多个装饰器的执行顺序是无序的,但执行过程是有序的。
装饰器执行过程是:遇到外接函数就跳转到另一个装饰器中执行,若再另一个装饰器中遇到同样的外接函数,则继续执行
证明1:多个装饰器的执行顺序是无序的
#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
def extend(func):
def wrapper(*args, **kwargs):
print "Begin AAAAAA"
func(*args, **kwargs)
print("A:%s"%(func.__name__))
print(reduce(lambda x,y:x+y, args), kwargs)
print "End AAAAA"
return wrapper
def extend1(func):
def wrapper(*args, **kwargs):
print "Begin BBBBB"
func(*args, **kwargs)
print("B:%s"%(func.__name__))
print(map(lambda x:x*2, args), kwargs)
print "End BBBBB"
return wrapper
@extend
@extend1
def get_time1(*args,**kwargs):
begin_time = time.time()
for n in range(3,4):
time.sleep(1)
end_time = time.time()
print("run %d "% (end_time - begin_time))
#print(reduce(lambda x,y:x+y, args), kwargs)
if __name__ == "__main__":
get_time1(1,2,3,4,5,6,ma=1,du=2)
执行结果:先从第一个装饰器标志@extend开始
Begin AAAAAA
Begin BBBBB
run 1
B:get_time1
([2, 4, 6, 8, 10, 12], {'du': 2, 'ma': 1})
End BBBBB
A:wrapper
(21, {'du': 2, 'ma': 1})
End AAAAA
另一个例子:
#!/usr/bin/python
# -*- coding: utf-8 -*-
def dec1(func):
print("1111")
def wrapper(*args, **kwargs):
print("2222")
func()
print("3333")
return wrapper
def dec2(func):
print("aaaa")
def wrapper(*args, **kwargs):
print("bbbb")
func()
print("cccc")
return wrapper
@dec1
@dec2
def test():
print("test test")
test()
运行结果:从第二个装饰器标志@dec2开始
aaaa
1111
2222
bbbb
test test
cccc
3333
通过比较,多个解释器的执行顺序是无序的。若大家觉得证明不够严谨,可自己多添几个试试。
证明2:装饰器的执行过程是有序的
图1:
图2:
没看懂?没关系,进行步骤解析:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2018/8/20
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
补充:一个讲的很好的BLOG: https://blog.csdn.net/xiangxianghehe/article/details/77170585
相关文章