Python實(shí)現(xiàn)上下文管理器的方法
問(wèn)題
你想自己去實(shí)現(xiàn)一個(gè)新的上下文管理器,以便使用with語(yǔ)句。
解決方案
實(shí)現(xiàn)一個(gè)新的上下文管理器的最簡(jiǎn)單的方法就是使用 contexlib 模塊中的 @contextmanager 裝飾器。 下面是一個(gè)實(shí)現(xiàn)了代碼塊計(jì)時(shí)功能的上下文管理器例子:
import time from contextlib import contextmanager @contextmanager def timethis(label): start = time.time() try: yield finally: end = time.time() print('{}: {}'.format(label, end - start)) # Example use with timethis('counting'): n = 10000000 while n > 0: n -= 1
在函數(shù) timethis()
中,yield
之前的代碼會(huì)在上下文管理器中作為 __enter__()
方法執(zhí)行, 所有在 yield
之后的代碼會(huì)作為 __exit__()
方法執(zhí)行。 如果出現(xiàn)了異常,異常會(huì)在yield語(yǔ)句那里拋出。
下面是一個(gè)更加高級(jí)一點(diǎn)的上下文管理器,實(shí)現(xiàn)了列表對(duì)象上的某種事務(wù):
@contextmanager def list_transaction(orig_list): working = list(orig_list) yield working orig_list[:] = working
這段代碼的作用是任何對(duì)列表的修改只有當(dāng)所有代碼運(yùn)行完成并且不出現(xiàn)異常的情況下才會(huì)生效。 下面我們來(lái)演示一下:
>>> items = [1, 2, 3] >>> with list_transaction(items) as working: ... working.append(4) ... working.append(5) ... >>> items [1, 2, 3, 4, 5] >>> with list_transaction(items) as working: ... working.append(6) ... working.append(7) ... raise RuntimeError('oops') ... Traceback (most recent call last): File "<stdin>", line 4, in <module> RuntimeError: oops >>> items [1, 2, 3, 4, 5] >>>
討論
通常情況下,如果要寫一個(gè)上下文管理器,你需要定義一個(gè)類,里面包含一個(gè) __enter__() 和一個(gè) __exit__() 方法,如下所示:
import time class timethis: def __init__(self, label): self.label = label def __enter__(self): self.start = time.time() def __exit__(self, exc_ty, exc_val, exc_tb): end = time.time() print('{}: {}'.format(self.label, end - self.start))
盡管這個(gè)也不難寫,但是相比較寫一個(gè)簡(jiǎn)單的使用 @contextmanager
注解的函數(shù)而言還是稍顯乏味。
@contextmanager
應(yīng)該僅僅用來(lái)寫自包含的上下文管理函數(shù)。 如果你有一些對(duì)象(比如一個(gè)文件、網(wǎng)絡(luò)連接或鎖),需要支持 with
語(yǔ)句,那么你就需要單獨(dú)實(shí)現(xiàn) __enter__()
方法和 __exit__()
方法。
以上就是Python實(shí)現(xiàn)上下文管理器的方法的詳細(xì)內(nèi)容,更多關(guān)于Python實(shí)現(xiàn)上下文管理器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python實(shí)現(xiàn)iOS自動(dòng)化打包詳解步驟
這篇文章主要介紹了Python實(shí)現(xiàn)iOS自動(dòng)化打包詳解步驟,文中通過(guò)示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-10-10python通過(guò)偽裝頭部數(shù)據(jù)抵抗反爬蟲(chóng)的實(shí)例
下面小編就為大家分享一篇python通過(guò)偽裝頭部數(shù)據(jù)抵抗反爬蟲(chóng)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05python進(jìn)程池實(shí)現(xiàn)的多進(jìn)程文件夾copy器完整示例
這篇文章主要介紹了python進(jìn)程池實(shí)現(xiàn)的多進(jìn)程文件夾copy器,結(jié)合完整實(shí)例形式分析了Python基于多進(jìn)程與進(jìn)程池的文件操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-11-1110張動(dòng)圖學(xué)會(huì)python循環(huán)與遞歸問(wèn)題
今天為大家整理了十張動(dòng)圖GIFS,有助于認(rèn)識(shí)循環(huán)、遞歸、二分檢索等概念的具體運(yùn)行情況。代碼實(shí)例以Python語(yǔ)言編寫,非常不錯(cuò),感興趣的朋友跟隨小編一起學(xué)習(xí)吧2021-02-02Python安裝第三方庫(kù)的方法(pip/conda、easy_install、setup.py)
這篇文章主要介紹了Python安裝第三方庫(kù)(pip/conda、easy_install、setup.py)的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05Python中的os.path路徑模塊中的操作方法總結(jié)
os.path模塊主要集成了針對(duì)路徑文件夾的操作功能,這里我們就來(lái)看一下Python中的os.path路徑模塊中的操作方法總結(jié),需要的朋友可以參考下2016-07-07jmeter執(zhí)行python腳本的實(shí)現(xiàn)示例
本文主要介紹了jmeter執(zhí)行python腳本的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05python文件讀寫操作與linux shell變量命令交互執(zhí)行的方法
這篇文章主要介紹了python文件讀寫操作與linux shell變量命令交互執(zhí)行的方法,涉及對(duì)文件操作及Linux shell交互的技巧,需要的朋友可以參考下2015-01-01