python 装饰器实现事件绑定_Python装饰器是怎么实现的?
Python中的裝飾器是通過利用了函數(shù)特性的閉包實(shí)現(xiàn)的,所以在講裝飾器之前,我們需要先了解函數(shù)特性,以及閉包是怎么利用了函數(shù)特性的
① 函數(shù)特性
python中的函數(shù)特性總的來說有以下四點(diǎn):
1. 函數(shù)作為變量傳遞
def add(x):
return x + 1
a = add # 作為變量
說明:函數(shù)如果不加括號,是不會執(zhí)行的,代表的是一個(gè)函數(shù)對象,它是可以作為變量來傳遞
2.函數(shù)作為參數(shù)傳遞
def add(x):
return x + 1
def execute(f):
return f(3)
execute(add) # 作為參數(shù)
說明:一個(gè)函數(shù)可以接受另一個(gè)函數(shù)對象作為自己的參數(shù),并對函數(shù)對象進(jìn)行處理
3.函數(shù)作為返回值
def add(x):
return x + 1
def get_add():
return add # 作為返回值
說明:一個(gè)函數(shù)的返回值可以是另一個(gè)函數(shù)對象
4.函數(shù)嵌套及跨域訪問
def outer():
x = 1
def inner():
print(x) # 被嵌套函數(shù)inner內(nèi)部的x變量可以到封裝域去獲取
inner()
outer()
說明:一個(gè)函數(shù)(主函數(shù))內(nèi)部是可以嵌套另一個(gè)函數(shù)(子函數(shù))的,比如outer函數(shù)從內(nèi)部嵌套了inner。一個(gè)函數(shù)本地域沒有的變量,是可以跨到它的封裝域(主函數(shù)與子函數(shù)之間的范圍)去尋找的
② 閉包的實(shí)現(xiàn)
python中的裝飾器是通過閉包實(shí)現(xiàn)的,簡單地講,閉包就是引用了外部變量的內(nèi)部函數(shù),而閉包的實(shí)現(xiàn)正是利用了以上函數(shù)特性,下面我們來看看閉包是如何實(shí)現(xiàn)的:
def outer(x):
def inner(): # 函數(shù)嵌套
return x # 跨域訪問,引用了外部變量x
return inner # 函數(shù)作為返回值
closure = outer('外部變量') # 函數(shù)作為變量賦給closure
print(closure()) # 執(zhí)行閉包
執(zhí)行結(jié)果:
外部變量
說明:我們分析下這個(gè)流程,outer接收到'外部變量',傳給inner,作為它return的參數(shù),最后outer返回inner函數(shù),返回的inner函數(shù)作為變量傳遞給closure,最后執(zhí)行closure這個(gè)函數(shù)對象,實(shí)際上是執(zhí)行了inner這個(gè)函數(shù),返回了 '外部變量',這樣就實(shí)現(xiàn)了一個(gè)簡單的閉包
我們發(fā)現(xiàn)上面的閉包例子只用到了之前說的其中3個(gè)函數(shù)特性,函數(shù)作為參數(shù) 這個(gè)特性好像并沒用上,別急,我們一步步來,試想一下,outer的參數(shù)x是不是也可以是一個(gè)函數(shù)對象?
下面我們來改寫一下實(shí)現(xiàn)閉包的代碼:
def func():
return '函數(shù)func'
def outer(x):
def inner(): # 函數(shù)嵌套
return '戴了inner牌帽子的 ' + x() # 跨域訪問,引用了外部變量x
return inner # 函數(shù)作為返回值
closure = outer(func) # 函數(shù)func作為outer的參數(shù);函數(shù)作為變量賦給closure
print(func()) # 執(zhí)行原始函數(shù)
print(closure()) # 執(zhí)行閉包
執(zhí)行結(jié)果:
函數(shù)func
戴了inner牌帽子的 函數(shù)func
說明:我們看到打印的結(jié)果, 從 func() 到 closure(),我們是不是感覺函數(shù)func被裝飾了一番,變成了closure,具體是怎么裝飾的呢?
劃重點(diǎn)來了!!!!!!!!!!!
我們看到closure實(shí)際上是outer(func),func作為參數(shù)傳進(jìn)outer,outer的子函數(shù)inner對func返回的結(jié)果進(jìn)行了一番裝飾,返回了一個(gè)裝飾后的結(jié)果,最后outer返回inner,可以說inner就是裝飾后的func,這就是一個(gè)函數(shù)被裝飾的過程,重點(diǎn)在于執(zhí)行 outer(func) 這個(gè)步驟
③ 裝飾器語法糖 @
python給我們提供了語法糖 @,我們想執(zhí)行 outer(func) 的時(shí)候,只需要把outer函數(shù)@到func函數(shù)的上面就可以了
具體實(shí)現(xiàn)如下:
def outer(x):
def inner():
return '戴了inner牌帽子的 ' + x()
return inner
@outer
def func():
return '函數(shù)func'
print(func())
執(zhí)行結(jié)果:
戴了inner牌帽子的 函數(shù)func
說明:我們看到打印的結(jié)果跟我們執(zhí)行closure()的結(jié)果是一樣的,也就說明 加了outer裝飾器的func 等價(jià)于 outer(func),所以我們很清楚地知道裝飾器@的作用是什么了,就是拿來把被裝飾的函數(shù)作為參數(shù)傳遞到裝飾器函數(shù)里面加工的,最后執(zhí)行被裝飾函數(shù)的時(shí)候,就相當(dāng)于執(zhí)行了一個(gè)加工后的函數(shù)。
以上就是python中裝飾器的誕全生過程......ChrisYZX:Python裝飾器的誕生過程?zhuanlan.zhihu.com
總結(jié)
以上是生活随笔為你收集整理的python 装饰器实现事件绑定_Python装饰器是怎么实现的?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 表达式类型的实现数据结构_Redis系列
- 下一篇: python pickle反序列化漏洞_