<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # Python 閉包 > 原文: [https://www.programiz.com/python-programming/closure](https://www.programiz.com/python-programming/closure) #### 在本教程中,您將了解 Python 閉包,如何定義閉包以及使用它的原因。 ## 嵌套函數中的非局部變量 在了解什么是閉包之前,我們必須首先了解什么是嵌套函數和非局部變量。 在另一個函數內部定義的函數稱為嵌套函數。 嵌套函數可以訪問定義范圍的變量。 在 Python 中,默認情況下,這些非局部變量是只讀的,我們必須將它們明確聲明為非局部變量(使用[`nonlocal`關鍵字](/python-programming/keyword-list#nonlocal))才能進行修改。 以下是訪問非局部變量的嵌套函數的示例。 ```py def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) printer() # We execute the function # Output: Hello print_msg("Hello") ``` **輸出** ```py Hello ``` 我們可以看到嵌套`printer()`函數能夠訪問外層函數的非本地`msg`變量。 * * * ## 定義閉包函數 在上面的示例中,如果函數`print_msg()`的最后一行返回了`printer()`函數而不是調用它,將會發生什么情況? 這意味著該函數的定義如下: ```py def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) return printer # returns the nested function # Now let's try calling this function. # Output: Hello another = print_msg("Hello") another() ``` **輸出**: ```py Hello ``` 這很不尋常。 用字符串`"Hello"`調用`print_msg()`函數,并將返回的函數綁定到名稱`another`上。 調用`another()`時,盡管我們已經完成了`print_msg()`函數的執行,但仍會記住該消息。 這種將某些數據(在這種情況下為`"Hello`)附加到代碼的技術在 Python 中稱為**閉包**。 即使變量超出范圍或函數本身已從當前名稱空間中刪除,也將記住定義范圍中的該值。 嘗試在 Python Shell 中運行以下命令以查看輸出。 ```py >>> del print_msg >>> another() Hello >>> print_msg("Hello") Traceback (most recent call last): ... NameError: name 'print_msg' is not defined ``` 在這里,即使刪除原始函數,返回的函數仍然可以使用。 * * * ## 什么時候擁有閉包? 從上面的示例可以看出,當嵌套函數在其定義范圍內引用一個值時,在 Python 中會有一個閉包。 以下幾點總結了在 Python 中創建閉包必須滿足的條件。 * 我們必須有一個嵌套函數(函數在函數內部)。 * 嵌套函數必須引用在外層函數中定義的值。 * 外層函數必須返回嵌套函數。 * * * ## 什么時候使用閉包? 那么,閉包有什么好處呢? 閉包可以避免使用全局值,并提供某種形式的數據隱藏。 它還可以為該問題提供面向對象的解決方案。 當在一個類中實現的方法很少(大多數情況下是一個方法)時,閉包可以提供另一種更優雅的解決方案。 但是,當屬性和方法的數量變大時,最好實現一個類。 這是一個簡單的示例,其中閉包可能比定義類和創建對象更可取。 但是,偏好是您的全部。 ```py def make_multiplier_of(n): def multiplier(x): return x * n return multiplier # Multiplier of 3 times3 = make_multiplier_of(3) # Multiplier of 5 times5 = make_multiplier_of(5) # Output: 27 print(times3(9)) # Output: 15 print(times5(3)) # Output: 30 print(times5(times3(2))) ``` **輸出**: ```py 27 15 30 ``` [Python 裝飾器](/python-programming/decorator)也廣泛使用了閉包。 最后,最好指出可以發現外層函數中包含的值。 所有函數對象都具有`__closure__`屬性,如果它是閉包函數,則該屬性返回單元格對象的元組。 參考上面的示例,我們知道`times3`和`times5`是閉包函數。 ```py >>> make_multiplier_of.__closure__ >>> times3.__closure__ (<cell at 0x0000000002D155B8: int object at 0x000000001E39B6E0>,) ``` 單元格對象具有存儲關閉值的屬性`cell_contents`。 ```py >>> times3.__closure__[0].cell_contents 3 >>> times5.__closure__[0].cell_contents 5 ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看