7
在this question中,我定義了一個包含上下文管理器的上下文管理器。什麼是最簡單的方法來完成這種嵌套?我最終打電話self.temporary_file.__enter__()
在self.__enter__()
。但是,在self.__exit__
中,我很確定我必須在finally塊中調用self.temporary_file.__exit__(type_, value, traceback)
以防發生異常。如果self.__exit__
中出現問題,我應該設置type_,value和traceback參數嗎?我檢查了contextlib
,但找不到任何工具來幫助解決這個問題。從問題嵌套Python上下文管理器
原始代碼:
import itertools as it
import tempfile
class WriteOnChangeFile:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.temporary_file = tempfile.TemporaryFile('r+')
self.f = self.temporary_file.__enter__()
return self.f
def __exit__(self, type_, value, traceback):
try:
try:
with open(self.filename, 'r') as real_f:
self.f.seek(0)
overwrite = any(
l != real_l
for l, real_l in it.zip_longest(self.f, real_f))
except IOError:
overwrite = True
if overwrite:
with open(self.filename, 'w') as real_f:
self.f.seek(0)
for l in self.f:
real_f.write(l)
finally:
self.temporary_file.__exit__(type_, value, traceback)
這真的很不錯。如果這個問題產生任何其他的好答案,我將暫時擱置一會兒。 – 2012-01-04 00:22:33
使用'@ contextlib.contextmanager'很方便,但仍然有些情況下適用於使用手動定義的'__enter__'和'__exit__'方法的類。你有這樣的建議嗎? – Zearin 2014-04-23 16:50:33
好吧,當它更方便的時候 - 例如當對象需要做的不僅僅是一個上下文管理器(儘管在這種情況下你還應該考慮添加一個@ contextlib.contextmanager方法)。 – 2015-09-11 16:08:05