之前同事問到兩個裝飾器在**中使用順序不同會不會有什麼問題,裝飾器是對被裝飾的函式做了一層包裝,然後執行的時候執行了被包裝後的函式,例如:
def decorator_a(fun):
def inner_a(*args, **kwargs):
print 'inner_a'
return fun(*args, **kwargs)
return inner_a
@decorator_a
def test():
print 'test_func'
test()
inner_a
test_func
在 python 中函式也是乙個物件,可以和其他物件一樣當作乙個引數傳遞,例如對於乙個普通的函式,可以傳遞一些引數,然後在函式裡對相應的引數進行操作,例如:
def normal(param):
print 'param:', param
normal('test')
param: test
type(normal)
function
而對於函式物件,可以如下進行傳遞:
def get_func(f):
print f.__name__
get_func(normal)
normal
所以上面使用的裝飾器語法糖其實和以下語句功能一樣,把 test 函式物件傳給了裝飾器函式,裝飾器函式的返回值是 1 個函式物件,然後把函式物件賦給了和原先傳進去的函式同名的變數,這樣新的變數也就是乙個函式物件了,對於函式物件,會和普通的函式一樣。當然,使用 @ 會使**看上去更加清晰:
def test():
print 'test_func'
test = decorator_a(test)
test()
上面是乙個裝飾器的情況,那麼如果有多個裝飾器,執行的順序是怎麼樣的呢?下面是另乙個裝飾器:
def decorator_b(fun):
def inner_b(*args, **kwargs):
print 'inner_b'
return fun(*args, **kwargs)
return inner_b
對於兩個裝飾器的執行順序如下:
# 1
@decorator_a
@decorator_b
def two():
print 'two'
two()
inner_a
inner_b
two# 2
@decorator_b
@decorator_a
def two():
print 'two'
two()
inner_b
inner_a
two# 3
two = decorator_b(decorator_a(two))
two()
inner_b
inner_a
two
到這裡,也就大概明白了裝飾器的執行順序以及簡單原理,回到開頭,對於使用中的多個裝飾器,還是需要關注一下使用的順序的,例如乙個驗證是否登陸的裝飾器,需要在驗證使用者身份的裝飾器上面。大概如下:
@login_in
@check_role
def hhh():
pass
Python 裝飾器執行順序
nisen的 python 裝飾器執行順序迷思 原址 裝飾器是python用於封裝函式或 的工具,網上可以搜到很多文章可以學習,我在這裡要討論的是多個裝飾器執行順序的乙個迷思。大部分涉及多個裝飾器裝飾的函式呼叫順序時都會說明它們是自上而下的,比如下面這個例子 def decorator a func...
python裝飾器執行順序
python 裝飾器 1 2層裝飾器 def decorator func todo def args,kwargs todo func args,kwargs todo todo 3層裝飾器 def decorator3 a 0 b 0 todo def func todo def args,kw...
Python 裝飾器執行順序迷思
裝飾器是python用於封裝函式或 的工具,網上可以搜到很多文章可以學習,我在這裡要討論的是多個裝飾器執行順序的乙個迷思。大部分涉及多個裝飾器裝飾的函式呼叫順序時都會說明它們是自上而下的,比如下面這個例子 def decorator a func print get in decorator a d...