python 装饰器
1) 2层装饰器
def decorator(func):
# TODO
def wrapper(*args, **kwargs):
# TODO
func(*args, **kwargs)
# TODO
# TODO
return wrapper
- 3层装饰器
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def decorator3(a=0, b=0):
# TODO
def wrapper(func):
# TODO
def inner_wrapper(*args, **kwargs):
# TODO
func(*args, **kwargs)
# TODO
# TODO
return inner_wrapper
# TODO
return wrapper
此处a,b可为任意指定参数,但不可以更改。
3) 类装饰器, python中类本身是不可调用的, 需要实现__call__方法, 将类变为callable。
class decorator(object):
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
# TODO
self.func(*args, **kwargs)
# TODO
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class decorator2(object):
def __call__(self, func):
# TODO
def wrapper(*args, **kwargs):
# todo
func(*args, **kwargs)
# todo
# TODO
return wrapper
python装饰器使用闭包的方式提供aop的概念。不过需要注意,装饰器装饰的函数,无法通过func.__name__获得真正的函数名, 可以导入functools.wraps包装。
wraps实际上调用的update_wrapper。
2. python装饰器的执行顺序。
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
import time
def log(level="info"):
print "log"
def wrapper(f):
print "wrapper start"
def inner_wrapper(*args, **kwargs):
print "inner_wrapper start"
print "{0}: {1}".format(level, time.time())
f(*args, **kwargs)
print "{0}: {1}".format(level, time.time())
print "inner_wrapper end"
print "wrapper end"
return inner_wrapper
print "end"
return wrapper
def log2(f):
print "log2..."
def wrapper(*args, **kwargs):
print "log2"
f(*args, **kwargs)
print "log2"
print "log2..."
return wrapper
@log2
@log(level="debug")
def test(a, b):
print a, b
执行test,输出
参见:https://segmentfault.com/a/1190000007837364
多个装饰器是按从下到上的顺序执行的, 在上图的例子中,test可以简化为test=log2(log(test)), 先执行log装饰器inner_wrapper外层的,得到inner_wrapper, 此时inner_wrapper是log2, 得到log2的wrapper, 此wrapper封装的func是log的inner_wrapper, 依次顺序执行,
结果如上图所示。