Python 裝飾器的誕生過程

 

Python中的裝飾器是經過利用了函數特性的閉包實現的,因此在講裝飾器以前,咱們須要先了解函數特性,以及閉包是怎麼利用了函數特性的python

① 函數特性

Python中的函數特性總的來講有如下四點:跨域

1. 函數做爲變量傳遞閉包

def add(x):
    return x + 1
a = add                    # 做爲變量

說明:函數若是不加括號,是不會執行的,表明的是一個函數對象,它是能夠做爲變量來傳遞app

2. 函數做爲參數傳遞函數

def add(x):
    return x + 1
def execute(f):
    return f(3)
execute(add)                # 做爲參數

說明:一個函數能夠接受另外一個函數對象做爲本身的參數,並對函數對象進行處理spa

3. 函數做爲返回值code

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。
一個函數本地域沒有的變量,是能夠跨到它的封裝域(主函數與子函數之間的範圍)去尋找的blog

② 閉包的實現

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中裝飾器的誕全生過程……

做者:ChrisYZX
連接:

https://www.jianshu.com/p/422a01f8532b
來源:簡書

-END-


 

     識別圖中二維碼,領取python全套視頻資料

相關文章
相關標籤/搜索