Python中閉包及循環變量的一點注意事項

閉包是編程語言通用的一種編程范式,且是面試中必問的問題之一。初學者可能在閉包中糾結好一陣子,當時學習JavaScript時我也在這里踩了不少坑,以Python的閉包為例寫點注意事項就當是學習的一點總結吧。

高階函數除了可以將函數作為參數之外,還可以將函數作為結果值返回,閉包的具體定義可以谷歌一下,通俗點來講,閉包就是返回函數以及函數的自我調用,我是這么理解的。以如下最精簡的函數為例解釋閉包:


當我們調用函數f時,返回的并不是階乘結果,而是返回的g函數體



調用返回結果才會返回階乘結果



注:不可直接調用函數內部的函數,即g()

我們在函數f內部定義了函數g,內部函數可以引用外部函數f的參數和局部變量,當函數f返回函數g時,相關的參數和局部變量都保存在返回的函數g中,這種就成為閉包。

需要注意的問題是,返回的函數并沒有立刻執行,而是直到調用了f()才執行。我們來看一個例子:


可能有人會猜想結果為1,4,9,實際執行打印出來的結果如下


原因就在于返回的函數引用了變量i,但它并非立刻執行。等到3個函數都返回時,它們所引用的變量i已經變成了3,因此最終結果為9。

返回閉包時牢記的一點就是:返回函數不要引用任何循環變量,或者后續會發生變化的變量。

如果一定要引用循環變量怎么辦?方法是再創建一個函數,用該函數的參數綁定循環變量當前的值,無論該循環變量后續如何更改,已綁定到函數參數的值不變:


這回執行結果符合預期了:


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 86.復合 Cases 共享相同代碼塊的多個switch 分支 分支可以合并, 寫在分支后用逗號分開。如果任何模式...
    無灃閱讀 1,433評論 1 5
  • 要點: 函數式編程:注意不是“函數編程”,多了一個“式” 模塊:如何使用模塊 面向對象編程:面向對象的概念、屬性、...
    victorsungo閱讀 1,562評論 0 6
  • Python進階框架 希望大家喜歡,點贊哦首先感謝廖雪峰老師對于該課程的講解 一、函數式編程 1.1 函數式編程簡...
    Gaolex閱讀 5,524評論 6 53
  • 之前沒有了解過Rxjava的童鞋,建議先閱讀《Rxjava 從入門到開發》這篇文章,對入門比較有幫助。 Start...
    Forrest32閱讀 667評論 0 8
  • 高原上 那青草 千年搖曳 草地上 那羚羊 呼嘯而過 騎著馬的女子 低頭和長發 山尖上的男子 仰頭和悵惘 那笑聲 激...
    南京遇上西京閱讀 399評論 0 2