Python實(shí)現(xiàn)上下文管理器的方法
問題
你想自己去實(shí)現(xiàn)一個新的上下文管理器,以便使用with語句。
解決方案
實(shí)現(xiàn)一個新的上下文管理器的最簡單的方法就是使用 contexlib 模塊中的 @contextmanager 裝飾器。 下面是一個實(shí)現(xiàn)了代碼塊計(jì)時功能的上下文管理器例子:
import timefrom contextlib import contextmanager@contextmanagerdef timethis(label): start = time.time() try: yield finally: end = time.time() print(’{}: {}’.format(label, end - start))# Example usewith timethis(’counting’): n = 10000000 while n > 0: n -= 1
在函數(shù) timethis() 中,yield 之前的代碼會在上下文管理器中作為 __enter__() 方法執(zhí)行, 所有在 yield 之后的代碼會作為 __exit__() 方法執(zhí)行。 如果出現(xiàn)了異常,異常會在yield語句那里拋出。
下面是一個更加高級一點(diǎn)的上下文管理器,實(shí)現(xiàn)了列表對象上的某種事務(wù):
@contextmanagerdef list_transaction(orig_list): working = list(orig_list) yield working orig_list[:] = working
這段代碼的作用是任何對列表的修改只有當(dāng)所有代碼運(yùn)行完成并且不出現(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 timeclass 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 應(yīng)該僅僅用來寫自包含的上下文管理函數(shù)。 如果你有一些對象(比如一個文件、網(wǎng)絡(luò)連接或鎖),需要支持 with 語句,那么你就需要單獨(dú)實(shí)現(xiàn) __enter__() 方法和 __exit__() 方法。
以上就是Python實(shí)現(xiàn)上下文管理器的方法的詳細(xì)內(nèi)容,更多關(guān)于Python實(shí)現(xiàn)上下文管理器的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. asp中response.write("中文")或者js中文亂碼問題2. 詳解CSS偽元素的妙用單標(biāo)簽之美3. ASP刪除img標(biāo)簽的style屬性只保留src的正則函數(shù)4. 詳解JS前端使用迭代器和生成器原理及示例5. XML入門的常見問題(四)6. html小技巧之td,div標(biāo)簽里內(nèi)容不換行7. 使用css實(shí)現(xiàn)全兼容tooltip提示框8. php bugs代碼審計(jì)基礎(chǔ)詳解9. ASP中格式化時間短日期補(bǔ)0變兩位長日期的方法10. 詳解PHP實(shí)現(xiàn)HTTP服務(wù)器過程
