python中的裝飾器是通過利用了函式特性的閉包實現的,所以在講裝飾器之前,我們需要先了解函式特性,以及閉包是怎麼利用了函式特性的。
一、函式特性
python中的函式特性總的來說有以下四點:
1. 函式作為變數傳遞
def add(x):
return
x +
1
a = add
# 作為變數
說明:函式如果不加括號,是不會執行的,代表的是乙個函式物件,它是可以作為變數來傳遞。
2.函式作為引數傳遞
def add(x):
return
x +
1
def excute(f):
returnf(3
)
excute(add)
# 作為引數
說明:乙個函式可以接受另乙個函式物件作為自己的引數,並對函式物件進行處理。
3.函式作為返回值
def add(x):
return
x +
1
def get_add():
return
add
# 作為返回值
說明:乙個函式的返回值可以是另乙個函式物件。
4.函式巢狀及跨域訪問
def outer():
x =
1
def inner():
print(x)
# 被巢狀函式inner內部的x變數可以到封裝域去獲取
inner()
outer()
說明:乙個函式(主函式)內部是可以巢狀另乙個函式(子函式)的,比如outer函式從內部巢狀了inner。乙個函式本地域沒有的變數,是可以跨到它的封裝域(主函式與子函式之間的範圍)去尋找的。
二、閉包的實現
python中的裝飾器是通過閉包實現的,簡單地講,閉包就是引用了外部變數的內部函式,而閉包的實現正是利用了以上函式特性,下面我們來看看閉包是如何實現的:
def outer(x):
def inner():
# 函式巢狀
return
x # 跨域訪問,引用了外部變數x
return
inner
# 函式作為返回值
closure = outer(
'外部變數'
) # 函式作為變數賦給closure
print(closure())
# 執行閉包
執行結果:
外部變數
說明:我們分析下這個流程,outer接收到'外部變數',傳給inner,作為它return的引數,最後outer返回inner函式,返回的inner函式作為變數傳遞給closure,最後執行closure這個函式物件,實際上是執行了inner這個函式,返回了 '外部變數',這樣就實現了乙個簡單的閉包。
我們發現上面的閉包例子只用到了之前說的其中3個函式特性,函式作為引數 這個特性好像並沒用上,別急,我們一步步來,試想一下,outer的引數x是不是也可以是乙個函式物件?
下面我們來改寫一下實現閉包的**:
def func():
return
'函式func'
def outer(x):
def inner():
# 函式巢狀
return
'戴了inner牌帽子的 '
+ x()
# 跨域訪問,引用了外部變數x
return
inner
# 函式作為返回值
closure = outer(func)
# 函式func作為outer的引數;函式作為變數賦給closure
print(func())
# 執行原始函式
print(closure())
# 執行閉包
執行結果:
函式
func
戴了inner牌帽子的 函式func
說明:我們看到列印的結果, 從 func() 到 closure(),我們是不是感覺函式func被裝飾了一番,變成了closure,具體是怎麼裝飾的呢?
我們看到closure實際上是outer(func),func作為引數傳進outer,outer的子函式inner對func返回的結果進行了一番裝飾,返回了乙個裝飾後的結果,最後outer返回inner,可以說inner就是裝飾後的func,這就是乙個函式被裝飾的過程,重點在於執行 outer(func) 這個步驟。
三、裝飾器語法糖 @
python給我們提供了語法糖 @,我們想執行 outer(func) 的時候,只需要把outer函式@到func函式的上面就可以了。
具體實現如下:
def outer(x):
def inner():
return
'戴了inner牌帽子的 '
+ x()
return
inner
@outer
def func():
return
'函式func'
print(func())
執行結果:
戴了inner牌帽子的 函式func
說明:我們看到列印的結果跟我們執行closure()的結果是一樣的,也就說明 加了outer裝飾器的func 等價於 outer(func),所以我們很清楚地知道裝飾器@的作用是什麼了,就是拿來把被裝飾的函式作為引數傳遞到裝飾器函式裡面加工的,最後執行被裝飾函式的時候,就相當於執行了乙個加工後的函式。
以上就是python中裝飾器的誕生過程。
原文發布時間為:2018-09-16
Python 裝飾器的誕生過程
python中的裝飾器是通過利用了函式特性的閉包實現的,所以在講裝飾器之前,我們需要先了解函式特性,以及閉包是怎麼利用了函式特性的 python中的函式特性總的來說有以下四點 1.函式作為變數傳遞 def add x return x 1 a add 作為變數 說明 函式如果不加括號,是不會執行的,...
Python 裝飾器的誕生過程
python中的裝飾器是通過利用了函式特性的閉包實現的,所以在講裝飾器之前,我們需要先了解函式特性,以及閉包是怎麼利用了函式特性的 函式特性 python中的函式特性總的來說有以下四點 函式作為變數傳遞 def add x return x 1 a add 作為變數 說明 函式如果不加括號,是不會執...
網路造假者自述「名牌」誕生過程
用網路只花3000元從日本註冊了乙個註冊資金為100萬元人民幣的 皮包公司 足不出戶一人完成進原料 生產化妝品瓶子 灌裝 貼標等一系列化妝品生產程式,通過電腦合成,讓美國某著名節目主持人以及球星碧鹹姆的妻子維多利亞為這一名為 玫邇雅 的化妝品做了廣告代言 就在一切都按照他自己安排的程式順利進行的時候...