在學(xué)習(xí)python的時候,三大“名器”對沒有其他語言編程經(jīng)驗的人來說,應(yīng)該算是一個小難點,本次博客就博主自己對裝飾器、迭代器和生成器理解進(jìn)行解釋。
為什么要使用裝飾器
什么是裝飾器?“裝飾”從字面意思來誰就是對特定的建筑物內(nèi)按照一定的思路和風(fēng)格進(jìn)行美化的一種行為,所謂“器”就是工具,對于python來說裝飾器就是能夠在不修改原始的代碼情況下給其添加新的功能,比如一款軟件上線之后,我們需要在不修改源代碼和不修改被調(diào)用的方式的情況下還能為期添加新的功能,在python種就可以用裝飾器來實現(xiàn),同樣在寫代碼的時候也要考慮到后面的可擴(kuò)展性,下面我們來看一步一步的看一下python的裝飾器。
一個簡單例子引入無參裝飾器
先來看簡單的幾行代碼,代碼的運行結(jié)果是先睡2秒,再打印"hello boy!":
import timedef foo(): """打印""" time.sleep(2) print("Hello boy!")foo()我們現(xiàn)在我們需要為其添加一個程序計時功能,但是不能修改原始的代碼:
import timedef timmer(func): def wrapper(): """計時功能""" time_start=time.time() func() time_end=time.time() print("Run time is %f "%(time_end-time_start)) return wrapperdef foo(): """打印""" time.sleep(2) print("Hello boy!")foo=timmer(foo)foo()#運行結(jié)果Hello boy!Run time is 2.000446 看!我們沒有修改原來的代碼就實現(xiàn)了這個功能,因為函數(shù)也是對象,所以能夠?qū)⒑瘮?shù)foo當(dāng)做參數(shù)傳遞給了函數(shù)timmer。
在python中,有個更簡潔的方式來取代foo=timmer(foo),使用@timmer這種方式,這個在python中被稱為語法糖。
import timedef timmer(func): def wrapper(): """計時功能""" time_start=time.time() func() time_end=time.time() print("Run time is %f "%(time_end-time_start)) return wrapper@timmer #等于 foo=timmer(foo)def foo(): """打印""" time.sleep(2) print("Hello boy!")foo()下面我們來一步一步的分析函數(shù)的執(zhí)行過程:
1.導(dǎo)入time模塊
import time
2.定義函數(shù)timmer,定義函數(shù)并不會執(zhí)行函數(shù)內(nèi)的代碼
def timmer(func):
3.調(diào)用裝飾器,相當(dāng)于foo=timer(foo),就是把函數(shù)foo作為參數(shù)穿給了函數(shù)timmer
@timmer
4.運行函數(shù)timmer,接受了參數(shù) func=foo
def timmer(func):
5.在函數(shù)timmer內(nèi),定義了函數(shù)wrapper,wrapper函數(shù)內(nèi)部代碼也不執(zhí)行,然后將函數(shù)wrapper作為返回值返回
return wrapper
6.將返回值賦值給了foo,在第3步中,foo=timmer(foo),還記吧
@timmer #等于 foo=timmer(foo)
7.運行函數(shù)foo(),但是這里的函數(shù)已經(jīng)不是原來的那個函數(shù)了,可以打印foo,對的,因為之前我們將wrapper作為返回值傳給了foo,所以在這里執(zhí)行foo就是在執(zhí)行wrapper了,為了再確定這一點你也可打印wrapper,它們的內(nèi)存地址相同,所以都是指向同一個地址空間:
新聞熱點
疑難解答