2 回答

TA貢獻(xiàn)165條經(jīng)驗(yàn) 獲得超90個贊
>>>?len(range(2)) 2 >>>?a=len >>>?a(range(2)) 2
每次看到別人問關(guān)于 函數(shù)傳遞,調(diào)用,返回等問題時,我就很開心,哈哈。 因?yàn)槲乙彩菑倪@里開始出發(fā),迷上函數(shù)式編程的。感覺它比 OOP 更加抽象,也更加有意思。
好了不廢話了, 開始解題。 首先說上面的代碼: 第三行, 我們把len函數(shù) 賦值給了一個變量a, 接著在第四行,就可以調(diào)用函數(shù)a 了。 這說明函數(shù)本身和 Python 的其他對象一樣(如,數(shù)字 1,2;字符串:'aa' 等)是可以作為值去賦值給其他變量名的, 同時 函數(shù)也就可以作為 另一個函數(shù)的返回值。
def?make_adder(addend): ????def?adder(augend): ????????return?augend?+?addend ????return?adder ???? p?=?make_adder(23) print?(make_adder(23))????????????????????#(1) print?(p)?????????????????????????????????#(2) print?(p(100))????????????????????????????#(3) print?(p.__closure__)?????????????????????#(4) print?(p.__closure__[0].cell_contents)????#(5) ##下面是這5次?輸出,?請自動修正我用的?Python3.x?print()?語法 #(1)?<function?make_adder.<locals>.adder?at?0x0000019AE2F2E950> #(2)?<function?make_adder.<locals>.adder?at?0x0000019AE2F2E8C8> #(3)?123 #(4)?(<cell?at?0x0000019AE2BA8C18:?int?object?at?0x000000006767F1F0>,) #(5)?23
好, 我們依次解釋這五次輸出,順便講下 幾乎所有支持函數(shù)式編程的語言 都會有的概念: 閉包。這大概也是面試官最愿意問的問題吧:順嘴一提,面試者隨便一說,面試官點(diǎn)點(diǎn)頭,能最大程度緩解氣氛 是不? 哈哈, 反正我做面試的時候會問。
因?yàn)椋?make_adder 這個函數(shù)的返回值 是一個函數(shù), 并且調(diào)用這個函數(shù)時,必須傳遞一個參數(shù)(后面這個參數(shù)的值,就成為了p 的閉包中很重要的組成部分)。所以第一個print 很好理解,就是一個函數(shù)體(把在函數(shù)中定義的函數(shù) adder作為值 返回了)。
這第二個print 就和開篇的例子一個道理,講一個函數(shù)作為值賦值給一個變量名了, 那么變量p 也是一個函數(shù)體。
至于第三個,就是對于函數(shù)p 的調(diào)用, 自然 打印的就是這個函數(shù)執(zhí)行的結(jié)果,或者說是返回的結(jié)果。
好,從這里開始就是閉包了,閉包 和 詞法作用域(lexical scoping)的概念,復(fù)制過來也就是幾句簡單但是不怎么容易理解的話, 這里就不贅述了,想了解請用搜索引擎。簡單來說就是,當(dāng)一個函數(shù)被定義時,它擁有的不僅僅是定義時的那些邏輯代碼 還 擁有當(dāng)時(定義時)的變量環(huán)境。 Python作為一個以優(yōu)美著稱的語言,必須 可以拿出解釋這個概念的直觀方法, 那就是每個函數(shù) 都有一個 閉包屬性, 這第四次print 就是打印出了 函數(shù)的這個屬性, 它是一個元組,其元素是 cell 類型。
第五次 print ,就很簡單了, 就是打印出了, 函數(shù)的 閉包(tuple) 的第一個元素(cell)的內(nèi)容(cell_contents)。
說了這么多, 也不知道題主理解了沒有。總的來說, 正是由于 函數(shù)擁有閉包的這屬性, 才能在 其定義的外部調(diào)用時, 不會忘記 或者找不到 其應(yīng)該 附帶的一些變量(此例中的 23)。
如果將函數(shù)改成:
def?make_adder(addend): ????a?=?100 ????def?adder(augend): ????????return?augend?+?addend?+?a ????return?adder
五次輸出有什么不同呢? 請自行實(shí)驗(yàn),對比,領(lǐng)悟 Python 中 函數(shù)的閉包屬性。

TA貢獻(xiàn)12條經(jīng)驗(yàn) 獲得超18個贊
1、return adder ,輸出adder的內(nèi)存地址
2、p = return adder , 同樣是輸出adder的內(nèi)存地址
3、print make_adder(23)(100),調(diào)用adder函數(shù)返回23+100的值,這里23取的是make_adder函數(shù)的參數(shù)值,100是adder函數(shù)的參數(shù)值
添加回答
舉報