如何在使用with和try..except时关闭文件?
如何在使用with和try..except时关闭文件?
此问题在这里已经有答案了:
我写了这个例子来证明当异常发生时,__exit__
并没有被运行:
class A(object): def __enter__(self): print('enter') def __exit__(self): print('exit') try: with A() as a: raise RunTimeError() except Exception as e: print('except')
输出结果:
enter except
话虽如此,正确使用with
语句并捕获异常的方法是什么,同时确保在结束时运行__exit__
呢?
谢谢!
admin 更改状态以发布 2023年5月22日
无论是否在with
主体中引发错误,__exit__
函数都会被调用。您的函数需要具有额外的参数exc_type
(异常的类型),exc_value
(异常对象)和traceback
(生成的追溯)。\n\n如果with
主体没有引发Error
,则这三个参数的值为None
。如果存在错误,则它们采用上述描述的值。\n\n但是,您可以关闭文件,而不管是否存在错误,然后稍后处理错误。\n\n因此,例如,我们可以将其实现为:\n\n
class A(object): def __enter__(self): self.file = open('some_file.txt') return self.file def __exit__(self, exc_type, exc_value, traceback): print(('exit', exc_type, exc_value, traceback)) # close the file, regardless of exceptions self.file.close() return False # silence the exception?
\n\n现在如果我们写一些像这样的东西:\n\n
with A(): raise Exception
\n\n我们会得到异常,__exit__
函数将会打印:\n\n
('exit',, Exception(), )
\n\n我们可以检查异常类、异常值和追溯,然后进行相应的处理。例如,基于异常,我们可能决定关闭文件、发送错误报告、中止SQL事务或不这样做。\n\n__exit__
函数还具有返回值(如果没有指定,则Python函数返回None
)。如果__exit__
函数返回具有真值True
的对象,则它将抑制异常:异常不会在with
块外引发。否则,它将在with
块外引发。例如,在我们的示例中,我们仍然收到异常。\n\n
class SilenceExceptions(object): def __enter__(self): pass def __exit__(self, exc_type, exc_value, traceback): return True # silence ALL exceptions
\n\n如果我们现在调用:\n\n
with SilenceExceptions(): raise Error
\n\n我们不会看到异常,因为它被“捕获”在__exit__
函数中。