1. 程式人生 > >Python零基礎入門之函式的修飾器詳解!

Python零基礎入門之函式的修飾器詳解!

內嵌函式

要理解修飾器,首先要知道python的內嵌函式。

  1. 在函式內部可以建立另外一個函式,不過內部函式也只能在外部函式的作用域之內呼叫才有效。
  2. 如果內部函式定義中包含了外部函式定義的物件的引用,內部函式會被稱為閉包

私信小編007即可獲取小編精心準備的大禮包一份哦!

修飾器

修飾器本質上是一個Python函式,它可以給物件函式新增額外功能而不必修改其內部程式碼。

語法糖與真正的裝飾器

@是修飾器函式的語法糖,常見的修飾器寫法如下(修飾器函式funA去修飾funB):

@funA
funB():
 print("funB列印")

@funA的過程類似於在定義完funA和funB後,再呼叫funA,funB=funA(funB),這句才是真正的裝飾器。

修飾器函式的定義

由上可見修飾器函式funA是一個接收函式物件為引數,並返回一個函式物件的函式。funA一般定義成類似下面的結構:

funA(fun):
 print("裝飾過程列印")
 inner():
 print("裝飾內容列印")
 fun()
 return inner 

其中print("裝飾過程列印")這部分不在inner中的內容,是會在@funA的時候就執行一次輸出。而inner內部的過程,則是要等到funB被呼叫的時候才會執行,即是說funB()實際執行的是funA.inner這個閉包函式。

多個修飾器

當一個函式被多個修飾器修飾時,他的執行順序如下:

def funA(fun):
 print('----用funA修飾----')
 def inner():
 print('----funA----')
 return '<a>' + fun() + '</a>'
 return inner
def funB(fun):
 print('----用funB修飾----')
 def inner():
 print('----funB----')
 return '<b>' + fun() + '</b>'
 return inner
@funA
@funB
def funC():
 print('----funC----')
 return 'hello python decorator'

輸出結果:

----用funB修飾----
----用funA修飾----

可以發現,修飾過程由內至外,先進行funB的修飾,再進行funA的修飾,類似於先funC=funB(funC),再funC=funA(funC),合起來就是funC=funA(funB(funC));

然後再加上呼叫語句:

print(funC())

列印輸出如下:

----用funB修飾----
----用funA修飾----
----funA----
----funB----
----funC----
<a><b>hello python decorator</b></a>

同樣可以發現,執行過程由外至內,先進行funA的內嵌函式,列印“funA start”,在執行到fun()的時候,再去呼叫funB.inner()函式,列印“funB start”,再執行到fun()的時候,才去呼叫被修飾的函式,列印"funC",而返回值則一層層由內至外巢狀。

裝飾有引數的函式

被裝飾的函式有引數的話,可以在 inner 函式裡面加上接受無名引數和關鍵字引數,然後fun(*args, **kwargs)把接收到的引數原封不動的傳回去。

funA(fun):
 inner(*args, **kwargs):
 fun(*args, **kwargs):
 return inner 

Python零基礎入門之函式的修飾器詳解!