目錄
一、函數以返回值
二、閉包
1、產生閉包的條件、作用
#2、閉包舉例
三、匿名函數lambda
首頁 後端開發 Python教學 Python中閉包Closure是什麼?有哪些應用?

Python中閉包Closure是什麼?有哪些應用?

Oct 13, 2018 pm 02:53 PM

這篇文章帶給大家的內容是關於Python中閉包Closure是什麼?有哪些應用?有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

一、函數以返回值

#介紹「閉包」之前,先了解函數作為傳回值的情況。
高階函數除了可以接收函數當參數外,還可以把函數當作結果值回傳。例如先前介紹的裝飾器中,就出現了將函數當作傳回值。

二、閉包

1、產生閉包的條件、作用

什麼是閉包?
當在函數中嵌套另一個函數時,如果內部函數引用了外部函數的變量,則可能產生閉包。
所以閉包產生的三個條件(缺一不可)

  • #1、必須嵌套一個內部函數

  • 2、內部函數必須引用外部函數的變數

  • 3、外部函數必須傳回內部函數

那為什麼要試用閉包,閉包的作用呢?

  • 1、閉包可以根據外部函數的局部變數來得到不同的結果

  • 2、當閉包執行完成後,仍可以保持目前的運行環境,執行結果依賴於函數上一次的運行結果

#2、閉包舉例

栗子一:求序列總和

>>> def calc_sum(*args):
...     ax = 0
...     for n in args:
...         ax = ax + n
...     return ax  # 返回变量
...
>>> calc_sum(1,2,3)
6
登入後複製

但是,現在如果要求不需要立即取得求和結果,而是在後面的程式碼中,根據需要再計算,該怎麼弄呢?
我們可以不傳回求和的結果,而傳回求和的函數,如下:

>>>def lazy_sum(*args):
...    def sum():            # sum()是内部函数,可以利用外部函数的参数
...        ax = 0
...        for n in args:    # sum()中使用外部函数的局部变量
...            ax = ax + n 
...        return ax
...    return sum            # 形成闭包,此时,*args保存在返回的函数中
...
>>>f = lazy_sum(1,3,5,7,9)
>>>f          # 此时返回的是求和函数
>>> f()       # 调用函数f()时,才真正计算求和的结果
25
登入後複製

注意:

lazy_sum()函數的內部執行順序,當f時,執行到return sum處,*args保存在回傳函數中,傳回的是sum()函數。執行f()時,相當於執行sum(),且包含*args。

當我們呼叫lazy_sun()時,每次都會回傳一個新的函數,即使傳入相同的參數,但是f()呼叫結果不影響。

我們來驗證第二點:

# 但是调用 f1() 与f2()的调用结果互不影响
>>> f1 = lazy_sum(1,3,5,7,9)
>>> f2 = lazy_sum(1,3,5,7,9)
>>> f1
<function lazy_sum.<locals>.sum at 0x013DD618>
>>> f2
<function lazy_sum.<locals>.sum at 0x02F92DF8>
>>> f1 == f2
False
>>> f1() == f2()
True
>>> f1()
25
>>> f2()
25
>>> id(f1())
1627215984
>>> id(f2())
1627215984
登入後複製

說明:f1與f2回傳函數的位置不一樣,所以f1==f2回傳結果為False。
但是不影響最後的執行結果,f1()與f2()的執行結果均為25,且用id()進行查看,指向是同一塊區域。

栗子二:

def count():
    fs = []
    for i in range(1, 4):
        def f():         # 返回函数f()放在循环里
            return i*i
    fs.append(f)
    return fs
f1, f2, f3 = count()
登入後複製

實際執行結果為:f1=9 f2=9 f3=9
可能與實際想的([1,4,9])有點不一樣。因為f()函數放在了for迴圈裡,只有當迴圈結束後,最後才回傳i=3的執行結果9。
所以回傳函數最好不要引用任何循環變量,或是後續可能變化的量。那如何來修改呢?

def count():
    def f(j):
        def g():
            return j*j      # 形成闭包
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i))      # 一个i值进入后,f(i)立刻被执行,并加入到fs中
    return fs

f1, f2, f3 = count()  # 返回函数g没有引用j
登入後複製

最後結果:[1,4,9] 即f1=1 f2=4 f3=

三、匿名函數lambda




  • ##定義:匿名函數指一類無需定義標識符函數名的函數或子程序。 Python允許使用lambda關鍵字創造匿名函數。

    語法:lambda 參數:表達式
  •   或lambda 形參1,…,形參n : function(形參),入參1,…,入參n
    #注意:1、lambda函數可以接收任意多個參數且傳回單一表達式的值;
  •   2、lambda中不能包含指令,傳回的表達式不能超過一個。

    優點:1、可以省去定義函數的過程,精簡程式碼;
  •   2、對於一些抽象的、不會重複使用的函數可以用lambda來定義。
######範例:###
>>> list( map( lambda x: x*x ,[1,2,3] ) )
[1, 4, 9]
登入後複製
###其中###lamdba x : x*x### 實作的是:###def f(x): return x*x#### 的功能。 ############可以把匿名函數賦值給一個變量,再利用變數呼叫該函數。例如:#########
>>> f = lambda x:x*x  
>>> f(5) # 调用
>>> g = lambda x,y=2 : x*y
>>> g(2,4)
8
>>> g(2)    # 默认y=2
4
登入後複製
########可以把匿名函數當作傳回值傳回,例如:#########
return lambda x:x*x
登入後複製

以上是Python中閉包Closure是什麼?有哪些應用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何解決Linux終端中查看Python版本時遇到的權限問題? 如何解決Linux終端中查看Python版本時遇到的權限問題? Apr 01, 2025 pm 05:09 PM

Linux終端中查看Python版本時遇到權限問題的解決方法當你在Linux終端中嘗試查看Python的版本時,輸入python...

如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到? 如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到? Apr 02, 2025 am 07:15 AM

使用FiddlerEverywhere進行中間人讀取時如何避免被檢測到當你使用FiddlerEverywhere...

在Python中如何高效地將一個DataFrame的整列複製到另一個結構不同的DataFrame中? 在Python中如何高效地將一個DataFrame的整列複製到另一個結構不同的DataFrame中? Apr 01, 2025 pm 11:15 PM

在使用Python的pandas庫時,如何在兩個結構不同的DataFrame之間進行整列複製是一個常見的問題。假設我們有兩個Dat...

Uvicorn是如何在沒有serve_forever()的情況下持續監聽HTTP請求的? Uvicorn是如何在沒有serve_forever()的情況下持續監聽HTTP請求的? Apr 01, 2025 pm 10:51 PM

Uvicorn是如何持續監聽HTTP請求的? Uvicorn是一個基於ASGI的輕量級Web服務器,其核心功能之一便是監聽HTTP請求並進�...

在Linux終端中使用python --version命令時如何解決權限問題? 在Linux終端中使用python --version命令時如何解決權限問題? Apr 02, 2025 am 06:36 AM

Linux終端中使用python...

如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎? 如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎? Apr 02, 2025 am 07:18 AM

如何在10小時內教計算機小白編程基礎?如果你只有10個小時來教計算機小白一些編程知識,你會選擇教些什麼�...

如何繞過Investing.com的反爬蟲機制獲取新聞數據? 如何繞過Investing.com的反爬蟲機制獲取新聞數據? Apr 02, 2025 am 07:03 AM

攻克Investing.com的反爬蟲策略許多人嘗試爬取Investing.com(https://cn.investing.com/news/latest-news)的新聞數據時,常常�...

See all articles