web-dev-qa-db-ja.com

Pythonの「open()」は「file not found」に対してさまざまなエラーをスローします-両方の例外を処理する方法は?

ユーザーが(開くファイルの)ファイル名を入力するように求められるスクリプトがあり、ファイルが現在のディレクトリに存在しない場合、ユーザーは再度求められます。これは短いバージョンです:

file = input("Type filename: ")

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

MacOS XでPython 3.3xでスクリプトをテストしたとき、意図的に間違ったファイル名を入力した場合、完全に正常に機能しました(「expect」の下でスイートを実行します)。

ただし、WindowsコンピューターでPython 3.2xでコードを実行したい場合、「FileNotFoundError」が定義されていないというエラーが表示されます。したがって、Python Windows上の3.2は、「FileNotFoundError」が変数であると見なし、プログラムはエラーで終了します。

入力ファイル名が有効でない場合、Python 3.2は「IOError」をスローします。LinuxマシンでPython 2.7、また、IOErrorでもあります。

私の問題は、コードが

except "FileNotFoundError":

windowsのPython 3.2では動作しませんが、

except "IOError":

私のMacではもう機能しません。

どうすれば回避できますか?私が考えることができる唯一の方法は、exceptだけを使用することです。これは通常は必要ありません。

41
user2015601

3.3では、 IOErrorOSErrorのエイリアスになりました であり、FileNotFoundErrorOSErrorのサブクラスです。だからあなたは試すかもしれない

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

これはかなり幅の広いネットをキャストし、例外がe.errno、しかしそれはあなたのユースケースをカバーするかもしれません。

PEP 3151 変更の理由を詳細に説明します。

65

これは、単純なexcept:、しかし、それが最善の解決策であるかどうかはわかりません:

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

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

したがって、ファイルが見つからない場合にのみ正確にキャッチするには、次のようにします。

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
5
Alex Che

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))

2
dm03514