【发布时间】:2013-08-26 06:13:55
【问题描述】:
来自上下文管理器上的datamodel docs:
注意
__exit__()方法不应重新引发传入的异常;这是调用者的责任。
我有一个临时文件,我想用close 释放它的文件描述符,但不向磁盘写入任何内容。我直观的解决方案是传递异常,但那是 discouraged in the docs - 当然是有充分理由的。
class Processor(object):
...
def write(self, *args, **kwargs):
if something_bad_happens:
raise RuntimeError('This format expects %s columns: %s, got %s.' % (
(len(self.cols), self.cols, len(args))))
self.writer.writerow(args)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
# the RuntimeError from write will be set as type, value and so on ..
# I'd like to close the stream here (release the file descriptor),
# but I do not leave a trace of the associated file -
# (one can always 'manually' delete with `os.remove` but maybe there's a
# better way ..?)
self.output_pipe.close()
另外,我不希望在这种特殊情况下在调用者中进行错误处理,原因有两个:
- 尽量减少调用者中的代码(见下文)
- 调用者对异常感到满意(我们想要快速失败)
上下文管理器是这样使用的:
class Worker(object):
...
def run(self):
# output setup so it will emit a three column CSV
with self.output().open('w') as output:
output.write('John', 'CA', 92101)
output.write('Jane', 'NY', 10304)
# should yield an error, since only three 'columns' are allowed
output.write('Hello', 'world')
更新:我的问题有点表述不当,因为我的问题实际上归结为:在嵌套的上下文管理器中,如何将异常传递给最外层的 CM?
【问题讨论】:
-
您真的是要在
__exit__中关闭输出两次吗? -
@user2357112,还有更多我没有在这里包含的代码 - 所以代码可能看起来很简洁,可能难以上下文化,抱歉。更新了我的问题,我没有关闭
output_pipe两次。
标签: python file exception resource-cleanup contextmanager