Python閉包與閉包陷阱舉例詳解
1 什么是閉包
在 Python 中,閉包是一種特殊的函數(shù),它能夠記住它所在的環(huán)境(也稱作上下文)。這意味著閉包能夠訪問定義它的作用域中的變量。閉包通常用于封裝數(shù)據(jù)和提供對外部訪問的接口。
在 Python 中使用閉包有以下幾點(diǎn)好處:
- 保存狀態(tài):閉包可以保存外部函數(shù)的狀態(tài),以便在內(nèi)部函數(shù)中使用。
- 簡化代碼:閉包可以簡化代碼結(jié)構(gòu),使得復(fù)雜的邏輯變得簡單易懂。
- 模塊化編程:閉包可以更好地封裝代碼,提高代碼的可重用性。
- 保證函數(shù)線程安全:閉包可以保證函數(shù)的線程安全性,避免全局變量被多線程修改。
2 閉包示例代碼
代碼示例如下:
def outer_func(x):
def inner_func(y):
return x + y
return inner_func
closure = outer_func(10)
print(closure(5)) # 15
這是一個(gè)閉包的示例代碼,其中outer_func是外部函數(shù),它返回一個(gè)內(nèi)部函數(shù)inner_func。內(nèi)部函數(shù)使用了外部函數(shù)的變量x,并且在被調(diào)用時(shí)使用了參數(shù)y。因此,當(dāng)我們調(diào)用outer_func(10)時(shí),它返回了一個(gè)閉包(即inner_func),它記錄了x=10的值。之后,我們可以調(diào)用這個(gè)閉包,并傳入?yún)?shù)y來計(jì)算結(jié)果。
3 什么是閉包陷阱
Python中的閉包陷阱指的是在閉包中引用了變量時(shí),如果該變量在閉包外部被修改,則閉包內(nèi)部的值也會(huì)改變。這可能會(huì)導(dǎo)致程序的錯(cuò)誤或意外行為。
4 閉包陷阱代碼實(shí)例
請對比以下兩組代碼
4.1 第一組代碼實(shí)例
def closure1():
l = []
for i in range(3):
def inner(i_=i):
return i_**2
l.append(inner)
return l
l1 = closure1()
print([i() for i in l1])
在執(zhí)行代碼時(shí),首先i的在range(3)中獲取的值為0,接下來執(zhí)行l.append(inner)。這里inner并沒有括號,所以inner本身不會(huì)被執(zhí)行,而是在l中添加了一個(gè)inner函數(shù)對象。并且inner函數(shù)的形參i_默認(rèn)值為0。

接下來,在for循環(huán)的作用下,l又被重復(fù)添加了兩次inner對象,其中i_的默認(rèn)值分別為1和2。

執(zhí)行完closure1后,我們使用列表推到式去遍歷l1。
列表推導(dǎo)式中的i()使得inner對象被執(zhí)行。因?yàn)?code>i()中未傳入任何參數(shù),所以其中的i_使用了我們定義的默認(rèn)參數(shù):0,1,2。在執(zhí)行完inner函數(shù)后,這些數(shù)字變成了0,1,4。因此最終的輸出即為[0,1,4] 。
以上是一段正常的非閉包代碼。
4.2 第二組代碼實(shí)例
def closure2():
l = []
for i in range(3):
def inner():
return i**2
l.append(inner)
print(inner.__closure__)
return l
l2 = closure2()
print([i() for i in l2])
這一組代碼和上面一組代碼沒有很大的區(qū)別,唯一的差異是,這一組代碼的inner并未傳入形參i_。inner中的i直接取自外部。
因此,在執(zhí)行closure2中的for循環(huán)時(shí),l中依然會(huì)被傳入3個(gè)inner函數(shù)對象,唯一的區(qū)別是傳入的對象沒有指定形參的默認(rèn)值。
在執(zhí)行[i() for i in l2]這個(gè)列表推到式時(shí),inner函數(shù)并未找到對i的賦值,因此回到外部的closure2中去尋找,并找到了i的值為3。
因此,對于這段代碼,每一個(gè)inner函數(shù)對象的輸出都是4。
很明顯這并不是我們想要的結(jié)果,這就是一個(gè)典型的閉包陷阱。
總結(jié)
到此這篇關(guān)于Python閉包與閉包陷阱舉例的文章就介紹到這了,更多相關(guān)Python閉包與閉包陷阱內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Opencv圖像處理:如何判斷圖片里某個(gè)顏色值占的比例
這篇文章主要介紹了Opencv圖像處理:如何判斷圖片里某個(gè)顏色值占的比例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
python修改字典內(nèi)key對應(yīng)值的方法
這篇文章主要介紹了python修改字典內(nèi)key對應(yīng)值的方法,涉及Python中字典賦值的相關(guān)實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07
PyQt5實(shí)現(xiàn)用戶登錄GUI界面及登錄后跳轉(zhuǎn)
PyQt5是強(qiáng)大的GUI工具之一,通過其可以實(shí)現(xiàn)優(yōu)秀的桌面應(yīng)用程序。本文主要介紹了PyQt5實(shí)現(xiàn)用戶登錄GUI界面及登錄后跳轉(zhuǎn),具有一定的參考價(jià)值,感興趣的可以了解一下2021-11-11
全面解析Python的While循環(huán)語句的使用方法
這篇文章主要介紹了全面解析Python的While循環(huán)語句的使用方法,是Python入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-10-10
Python抓取數(shù)據(jù)到可視化全流程的實(shí)現(xiàn)過程
這篇文章主要介紹了Python抓取數(shù)據(jù)到可視化全流程的實(shí)現(xiàn)過程,2022-01-01
Python中的函數(shù)式編程:不可變的數(shù)據(jù)結(jié)構(gòu)
今天小編就為大家分享一篇關(guān)于Python中的函數(shù)式編程:不可變的數(shù)據(jù)結(jié)構(gòu),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10
python制作定時(shí)發(fā)送信息腳本的實(shí)現(xiàn)思路
這篇文章主要介紹了python實(shí)現(xiàn)企業(yè)微信定時(shí)發(fā)送文本消息的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11

