沒看懂,前后邏輯關系
import time
def performance(f):
? ? def fn(*args, **kw):
? ? ? ? t1 = time.time()
? ? ? ? r = f(*args, **kw)
? ? ? ? t2 = time.time()
? ? ? ? print 'call %s() in %fs' % (f.__name__, (t2-t1))
? ? ? ? return r
? ? return fn
@performance
def factorial(n):
? ? return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
函數 factorial()與前面的performance()邏輯關系沒看明白,哪位大俠指導一下
2020-02-08
導入time?模塊?
然后開始定義我們的閉包函數,我之前不知道高階函數,都叫閉包,這只是個名字不要糾結
首先閉包至少兩層函數嵌套,這沒問題
那就定義一個performance函數,
接下來返回值要是一個函數,那就寫好return?一個函數,在開始定義里面函數
這一層內層函數一定要執行想要裝飾的函數本身,否則就不叫裝飾器了,而傳進來的函數就是performance的參數f,
即f?就是@performance這句代碼下面的函數?factorial,至于為什么是這個函數,那就是@語法的內部操作了.不用太糾結
所以在performance?和?fn這兩個函數空間內,都可以執行額外的操作.閉包的作用就是為了不改動源代碼?facorial?而進行額外操作.
你可以把?factorial(10)一步步分
factorial(10)
變成?factorial(10) =?performance(factorial)(10)? //?可以理解嗎?
由performance return?之后在變成? fn(10)? //因為只返回了fn函數 即return ?而不是返回fn()的調用結果??
所以變成了fn(10)?即變成調用fn,參數是10
r = f(*args, **kw)
這一句調用f?就是調用最外層當初傳進來的原始函數factorial
而里面的參數*args **kwargs?就是?fn(定義時的參數)
因為函數內部可以訪問傳進來的參數,這個好理解
*args **kwargs? 這種參數定義就為了解決我也不知道裝飾的函數有多少參數,反正全部接受在全部傳遞最保險
明白了嗎?
再加一句
@performance
def factorial(n):
????//這里是函數源代碼
這句裝飾可以理解為
執行函數前自動執行了 performance(factorial)
完整拆開理解就是
執行一次函數調用factorial(10)?裝飾后實際上執行?performance(factorial)(10)?即先吊用閉包函數
得到閉包內層函數之后在把原本參數10傳遞進內層函數,內層函數里面在調用原函數并且給參數10
就是不用直接調用,而是用函數來間接調用原函數
@裝飾器的好處就是省略performance(factorial)(10)的手寫過程.而且更好理解.只要用@裝飾了,還是直接寫原函數調用,邏輯簡單
2020-01-30