亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

沒看懂,前后邏輯關系

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()邏輯關系沒看明白,哪位大俠指導一下


正在回答

2 回答

導入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)的手寫過程.而且更好理解.只要用@裝飾了,還是直接寫原函數調用,邏輯簡單


7 回復 有任何疑惑可以回復我~
@performance?#?factorial?=?performance(factorial)
在題目執行print?factorial(10)過程中,首先是通過@performance,運行performance函數(此時用factorial函數作為參數,即f?=?factorial),
然后發現返回是fn,再運行fn函數,則運行閉包fn這個函數,其中ranhou?yudao?f(),則進行調用factorial函數即可
然后運行perfomance這個函數


2 回復 有任何疑惑可以回復我~

舉報

0/150
提交
取消
python進階
  • 參與學習       255526    人
  • 解答問題       3038    個

學習函數式、模塊和面向對象編程,掌握Python高級程序設計

進入課程

沒看懂,前后邏輯關系

我要回答 關注問題
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號