Python 捕获文件关闭异常的正确方法

Python proper way to catch exceptions on file close

我是 Perl 老手,刚接触 Python。我知道在 Perl 中 fd.close() 并不是无关紧要的。写满文件系统,close()会报错。同样对于套接字错误,它们出现在 close() 中。那么在Python中怎么办呢?一些示例显示将 open() 和 close() 放在同一个 try 块中,这会在其中一个上捕获 IOError。但其他示例在 finally 块中显示 close() 以在异常时关闭文件。但是,如果异常首先出现在close()中怎么办?

这是否涵盖了这两个要求? (1) 始终关闭文件 (2) 捕获所有 IO 异常?

try:
    with open(FILE, 'w') as fd:
        .....
except IOError as err:
    .....

谢谢, 克里斯

检查 ,一条评论说您可以单独打开文件以查找打开时的错误,然后将其用作上下文管理器并像这样再次尝试:

try:
    f = open( ... )
except IOError:
    ...
try:
    with f:
        ...
except IOError:
    ...

您的代码正确;当 with 块退出时,它无法区分 open 上的错误与(隐式)close 上的错误(也无法区分块中任何其他文件操作的错误),但它会捕获所有此类错误。当您到达 except 块时,您可以保证文件 已尝试 closewith 自动关闭将在你到达它,无论是通过失败还是引发异常),但如果异常发生在 close 期间,你的选择是有限的(因为从 close 失败中有意义地恢复通常是不可能的)。

请注意 IOError 并不完全正确;在 Py3 上它将按预期工作(它是 OSError 的别名,这是您要捕获的实际基本异常),而在 Python 2 上它与 OSError 分开,这意味着您不会捕获 OSError 或其子类(特别是在 Windows 系统上很常见)。

如果你想 明确地 可移植地捕获所有此类错误,你想捕获 EnvironmentError,它是 IOError 和 [= Python 2 上的 19=],Python 3 上 OSError 的别名;如果可移植性不是问题,那么 OSError 是 Py3 上实际使用的名称,因此您也可以使用记录的名称。