Python 的“open()”为“找不到文件”抛出不同的错误——如何处理这两个异常?

Posted

技术标签:

【中文标题】Python 的“open()”为“找不到文件”抛出不同的错误——如何处理这两个异常?【英文标题】:Python's "open()" throws different errors for "file not found" - how to handle both exceptions? 【发布时间】:2013-02-08 12:55:59 【问题描述】:

我有一个脚本,提示用户输入(要打开的文件的)文件名,如果当前目录中不存在该文件,则会再次提示用户。这是简短的版本:

file = input("Type filename: ")

...
try:
    fileContent = open(filename, "r")
    ...
except FileNotFoundError:
    ...

当我在我的 MacOS X 上使用 Python 3.3x 测试我的脚本时,当我故意输入错误的文件名时它运行得非常好(它在“预期”下执行套件)。

但是,当我想运行我的代码时 在 Python 3.2x 的 Windows 计算机上,我收到一条错误消息,指出“FileNotFoundError”未定义。因此,Windows 上的 Python 3.2 认为“FileNotFoundError”是一个变量,程序会因错误而退出。

我发现如果输入文件名无效,Windows 上的 Python 3.2 会抛出“IOError”。我在我的 Linux 机器上用 Python 2.7 对其进行了测试,它也是一个 IOError。

我现在的问题是,带有

的代码
except "FileNotFoundError":

不会在 Windows 的 Python 3.2 上运行,但如果我将其更改为

except "IOError":

它不再在我的 Mac 上工作了。

我该如何解决?我能想到的唯一方法就是使用 except,我通常不想要。

【问题讨论】:

这不是因为 Mac/Windows,而是 Python 的版本。我也会调查 OS X 上的 3.2/3.3(以及 Windows 上的 3.3),查阅更改日志,然后酌情修改问题/标题。 【参考方案1】:

在 3.3 中,IOError became an alias for OSErrorFileNotFoundErrorOSError 的子类。所以你可以试试

except (OSError, IOError) as e:
   ...

这将撒下一个非常广泛的网络,并且您不能在不检查 e.errno 的情况下假设异常是“找不到文件”,但它可能涵盖您的用例。

PEP 3151 详细讨论了更改的基本原理。

【讨论】:

【参考方案2】:

这比简单的except: 让我印象深刻,但我不确定这是否是最佳解决方案:

error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError)

try:
    f = open('.....')
except error_to_catch:
    print('!')

【讨论】:

在其他新闻中 except: 后跟一个逗号在语法上是正确的,但仍然看起来很奇怪。 这也是一个很好的解决方案。比except(IOError, OSError): 长一点,但更具体 这是一种反模式。【参考方案3】:

所以要准确捕获文件未找到时,我会这样做:

import errno
try:
   open(filename, 'r')
except (OSError, IOError) as e: # FileNotFoundError does not exist on Python < 3.3
   if getattr(e, 'errno', 0) == errno.ENOENT:
      ... # file not found
   raise

【讨论】:

【参考方案4】:

您可以同时捕获 2 个错误

except (FileNotFoundError, IOError):

我没有意识到这是您要问的。我希望有一个更有说服力的解决方案然后手动检查

try:
   error_to_catch = FileNotFoundError
except NameError:
   error_to_catch = IOError

except error_to_catch

cwallenpoole 在他的回答中更雄辩地做了这个条件 (error_to_catch = getattr(__builtins__,'FileNotFoundError', IOError))

【讨论】:

这项工作在哪里 - 我收到一个错误,指出“FileNotFoundError”未定义。因此,Windows 上的 Python 3.2 认为“FileNotFoundError”是一个变量,程序退出并出现错误 - ? @pst 有趣抱歉没有考虑到它

以上是关于Python 的“open()”为“找不到文件”抛出不同的错误——如何处理这两个异常?的主要内容,如果未能解决你的问题,请参考以下文章

Documents.Open使用FileSystemObject返回“5174 - 找不到文件”,但并非总是如此

关于在Spark集群中读取本地文件抛出找不到文件异常的问题

关于在Spark集群中读取本地文件抛出找不到文件异常的问题

Python打开文件open()的注意事项

逆向工程 找不到文件

试图移动图像文件,为输出目录抛出FileNotFoundException