49

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

file = input("Type filename: ")

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

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

但是,当我想在 Windows 计算机上使用 Python 3.2x 运行我的代码时,我收到一条错误消息,指出未定义“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我通常不想要的 just 。

4

4 回答 4

77

在 3.3 中,IOError成为 的别名OSError,并且FileNotFoundError是 的子类OSError。所以你可以试试

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

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

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

于 2013-02-22T20:11:48.523 回答
9

这让我觉得比简单的要好except:,但我不确定它是否是最好的解决方案:

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

try:
    f = open('.....')
except error_to_catch:
    print('!')
于 2013-02-22T20:13:54.907 回答
7

因此,只有在找不到文件时才能准确捕获,我这样做:

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
于 2016-09-09T14:39:11.867 回答
2

您可以同时捕获 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))

于 2013-02-22T19:49:24.753 回答