Python學習之路 裝飾器(2)

2021-09-28 14:23:16 字數 1483 閱讀 1118

#coding=utf-8

def f1(func):

print('in f1')

def f1_inner():

print('in f1_inner')

func()

return f1_inner

def f2(func):

print('in f2')

def f2_inner():

print('in f2_inner')

func()

return f2_inner

@f1@f2

def f():

print('in f')

if __name__ == '__main__':

pass

#f()

結果:in f2

in f1

在上面的這個例子中裝飾器f1和f2都是用來修飾函式f的,且順序時f1在前f2在後。沒有呼叫函式f,得到的列印結果如上。原因是:裝飾器是用來修飾函式的,當python直譯器讀到@f1時發現下面的不是函式,而是另乙個裝飾器f2,因此才優先執行了f2,當f2執行完後,f2返回的才是乙個函式的引用,因此才返回來執行f1。因此得出結論:裝飾器本身的執行順序和修飾順序相反

那麼加上函式呼叫後結果又是怎樣的呢?

#coding=utf-8

def f1(func):

print('in f1')

def f1_inner():

print('in f1_inner')

func()

return f1_inner

def f2(func):

print('in f2')

def f2_inner():

print('in f2_inner')

func()

return f2_inner

@f1@f2

def f():

print('in f')

if __name__ == '__main__':

#pass

f()結果:in f2

in f1

in f1_inner

in f2_inner

in f

分析一下為什麼是這個結果:如果上面的例子沒問題的話,前兩行的結果是毋庸置疑的。然後我們把裝飾器**那裡的三行**加個注釋,如下:

@f1   #f = f1(f)

@f2 #f = f2(f)

def f():

print('in f')

這個換成閉包的 呼叫語句,因為裝飾器f2比f1更近修飾函式f,因此函式f第一次返回的是f2中f2_inner的引用,然後才是f1中f1_inner函式的引用,最後才是函式f本身。由此得出:在多個裝飾器修飾乙個函式時,執行順序是由內層裝飾器向外側開始的,最後才是被修飾的函式,

Python學習之路 裝飾器(1)

裝飾器本身是利用閉包實現的,因此只有真正學會了閉包中的知識點才能完全理解裝飾器的語法。試想乙個問題 在乙個工程中有乙個函式func 現在有乙個需求是func 現在本身不能滿足的,因此需要重新實現func 的功能。這是正常的思路,也是可行的,但是卻違背了開發中的 開放 封閉 原則。封閉 函式本身的功能...

Python學習之路 裝飾器(3)

上兩篇提到的裝飾器的例子中,被修飾的函式沒有引數,那麼如果修飾帶引數的裝飾器又該如何書寫呢?coding utf 8 def f1 func print in f1 def f1 inner print in f1 inner func return f1 inner f1def f a,b pri...

Python學習之路 裝飾器(4)

函式通常都是帶有返回值的,當裝飾器修飾帶有返回值的函式時該怎麼實現呢?coding utf 8 def f1 func print in func def f1 inner print in f1 inner value func return value return f1 inner f1def...