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, 依次順序執行,

結果如上圖所示。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM