python装饰器执行顺序

1. python 装饰器

    1) 2层装饰器       

def decorator(func):
    # TODO
    def wrapper(*args, **kwargs):
        # TODO
        func(*args, **kwargs)
        # TODO
    # TODO
    return wrapper

   2)  3层装饰器

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
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装饰器的执行顺序。

 1 import time
 2 
 3 
 4 def log(level="info"):
 5     print "log"
 6 
 7     def wrapper(f):
 8         print "wrapper start"
 9 
10         def inner_wrapper(*args, **kwargs):
11             print "inner_wrapper start"
12             print "{0}: {1}".format(level, time.time())
13             f(*args, **kwargs)
14             print "{0}: {1}".format(level, time.time())
15             print "inner_wrapper end"
16 
17         print "wrapper end"
18         return inner_wrapper
19 
20     print "end"
21     return wrapper
22 
23 
24 def log2(f):
25     print "log2..."
26 
27     def wrapper(*args, **kwargs):
28         print "log2"
29         f(*args, **kwargs)
30         print "log2"
31 
32     print "log2..."
33     return wrapper
34 
35 
36 @log2
37 @log(level="debug")
38 def test(a, b):
39     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, 依次顺序执行,

结果如上图所示。

 

posted @ 2018-05-28 11:04  淡季的风  阅读(1966)  评论(0编辑  收藏  举报