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

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

如何正確理解這三個return,個人理解在代碼注釋

import?time
def?performance(unit):
????def?log_decorator(f):
????????def?fn(*args,?**kw):
????????????t1=time.time()
????????????r=f(*args,?**kw)
????????????t2=time.time()
????????????print?'call?%s()?in?%f%s'?%?(f.__name__,t2-t1,unit)
????????????return?r????????#?返回f函數,即x*y?
????????return?fn??????#?閉包?為了傳參不受限制?
????return?log_decorator???#?閉包?
????
@performance('ms')
def?factorial(n):????
????return?reduce(lambda?x,y:?x*y,?range(1,?n+1))print?factorial(10)


正在回答

2 回答

然后開始定義我們的閉包函數,我之前不知道高階函數,都叫閉包,這只是個名字不要糾結

首先閉包至少兩層函數嵌套,這沒問題

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

這是我二層的回答,三層也就是在@函數名 這句上再加個()傳參調用罷了

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

個人拙見:

log_decorator(f) 這個是裝飾器,它為了裝飾 f 而存在,所以他有參數 f ,而在它內部有fn這個閉包,這個閉包是為了 傳 f 的參數設置的,所以它的參數為 *args, **kw,在它內部,除了r = f(*args, **kw), 其他都是裝飾,在裝飾完以后,必然要返回所裝飾的函數 f 即 return r.? 順著這個意義,外層自然要返回 fn,這里的fn就是r,順著內層一層層返回,到這里,普通的無參裝飾器就完事了,但這里裝飾器也有參數,所以再套一層performance(unit),把裝飾器參數傳進去,最后再順著上層返回log_decorator(也就是最內層的r)

總結一下,三層的裝飾器函數分別有不同的存在的意義:傳裝飾器參數、傳函數、傳函數參數

而三層裝飾器函數的返回值都是一個目的:返回原函數 f


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

sheeeeeeep

更正一下,,最內層返回的不是函數,而是這個原函數原本應該返回的結果(也就是說,裝飾器只是加功能,原函數的返回值是不變的),在上面的例子中就是 10! 這個數 次內層也就是裝飾器層它返回的才是一個函數(經過裝飾的原函數),最外層是接著次內層再返回同一個函數
2020-01-22 回復 有任何疑惑可以回復我~

舉報

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

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

進入課程

如何正確理解這三個return,個人理解在代碼注釋

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

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

幫助反饋 APP下載

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

公眾號

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