Python實現(xiàn)上下文管理器的方法
問題
你想自己去實現(xiàn)一個新的上下文管理器,以便使用with語句。
解決方案
實現(xiàn)一個新的上下文管理器的最簡單的方法就是使用 contexlib 模塊中的 @contextmanager 裝飾器。 下面是一個實現(xiàn)了代碼塊計時功能的上下文管理器例子:
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
之前的代碼會在上下文管理器中作為 __enter__()
方法執(zhí)行, 所有在 yield
之后的代碼會作為 __exit__()
方法執(zhí)行。 如果出現(xiàn)了異常,異常會在yield語句那里拋出。
下面是一個更加高級一點的上下文管理器,實現(xiàn)了列表對象上的某種事務:
@contextmanager def list_transaction(orig_list): working = list(orig_list) yield working orig_list[:] = working
這段代碼的作用是任何對列表的修改只有當所有代碼運行完成并且不出現(xiàn)異常的情況下才會生效。 下面我們來演示一下:
>>> 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] >>>
討論
通常情況下,如果要寫一個上下文管理器,你需要定義一個類,里面包含一個 __enter__() 和一個 __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))
盡管這個也不難寫,但是相比較寫一個簡單的使用 @contextmanager
注解的函數(shù)而言還是稍顯乏味。
@contextmanager
應該僅僅用來寫自包含的上下文管理函數(shù)。 如果你有一些對象(比如一個文件、網(wǎng)絡連接或鎖),需要支持 with
語句,那么你就需要單獨實現(xiàn) __enter__()
方法和 __exit__()
方法。
以上就是Python實現(xiàn)上下文管理器的方法的詳細內(nèi)容,更多關于Python實現(xiàn)上下文管理器的資料請關注腳本之家其它相關文章!
相關文章
python通過偽裝頭部數(shù)據(jù)抵抗反爬蟲的實例
下面小編就為大家分享一篇python通過偽裝頭部數(shù)據(jù)抵抗反爬蟲的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05python進程池實現(xiàn)的多進程文件夾copy器完整示例
這篇文章主要介紹了python進程池實現(xiàn)的多進程文件夾copy器,結(jié)合完整實例形式分析了Python基于多進程與進程池的文件操作相關實現(xiàn)技巧,需要的朋友可以參考下2019-11-11Python安裝第三方庫的方法(pip/conda、easy_install、setup.py)
這篇文章主要介紹了Python安裝第三方庫(pip/conda、easy_install、setup.py)的相關知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05Python中的os.path路徑模塊中的操作方法總結(jié)
os.path模塊主要集成了針對路徑文件夾的操作功能,這里我們就來看一下Python中的os.path路徑模塊中的操作方法總結(jié),需要的朋友可以參考下2016-07-07jmeter執(zhí)行python腳本的實現(xiàn)示例
本文主要介紹了jmeter執(zhí)行python腳本的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-05-05python文件讀寫操作與linux shell變量命令交互執(zhí)行的方法
這篇文章主要介紹了python文件讀寫操作與linux shell變量命令交互執(zhí)行的方法,涉及對文件操作及Linux shell交互的技巧,需要的朋友可以參考下2015-01-01