Pythonでファイルを読み取ろうとするときに例外を処理するための良い方法は何ですか?


86

Pythonで.csvファイルを読みたい。

  • ファイルが存在するかどうかはわかりません。
  • 私の現在の解決策は以下の通りです。2つの別々の例外テストがぎこちなく並置されているので、私にはだらしなく感じます。

それを行うためのより良い方法はありますか?

import csv    
fName = "aFile.csv"

try:
    with open(fName, 'rb') as f:
        reader = csv.reader(f)
        for row in reader:
            pass #do stuff here
    
except IOError:
    print "Could not read file:", fName

非既存のファイルがエラーケースはありませんが、おそらく状況が、その後のチェックと(と明示的に前にその不在/非可読性を扱う場合は別途に)try価値があるかもしれません。これは、os.path.exists(file)とでos.access(file, os.R_OK)それぞれ実行できます。このようなチェックは競合状態から解放されることはありませんが、ファイルが消えることはめったに通常の状況ではありません;)
stefanct 2017

2
この質問への回答は、おそらくpathlibモジュールの使用法を含むように更新する必要があります。これにより、この問題がはるかに簡単になり、おそらく標準のPythonプラクティスである必要があります(特に2.7にバックポートされたため)。
リックは2017

このキャッチしながらIOError、それがキャッチしていないcsv.ErrorCSV形式際にされていないファイルに起因するDialect.strict=Trueか、Error他のエラー(CSVパッケージのドキュメントによる)のために、その外側のtry、または単にファイルのチェックが存在する場合、CSV例外の内側の試みでありますおそらく正しい答えです。
ピンクのspikyhairman20年

@pinkspikyhairmanはい、例外ハンドラーで、処理するエラータイプを決定する必要があります。エラーの複数の特定のタイプを処理する方法については、こちらを参照してください:stackoverflow.com/questions/6470428/...
チャールズHolbrow

回答:


52

私は何が求められているのか誤解したと思います。もう一度読んでみると、ティムの答えはあなたが望むもののようです。ただし、これを追加します。からの例外をキャッチするopen場合openは、でラップする必要がありtryます。の呼び出しopenがのヘッダーにあるwith場合、例外をキャッチwithするには、がにあるtry必要があります。それを回避する方法はありません。

したがって、答えは「ティムのやり方」または「いいえ、正しくやっています」のいずれかです。


すべてのコメントが参照する以前の役に立たない答え:

import os

if os.path.exists(fName):
   with open(fName, 'rb') as f:
       try:
           # do stuff
       except : # whatever reader errors you care about
           # handle error


23
ファイルが存在するからといって、それを読むことができるとは限りません。
Gabe 2011

3
ファイルが存在することを確認してから開こうとするまでの間に、ファイルが(たとえば別のプロセスによって)削除される可能性があるため、これは完全ではありません。
Liquid_Fire 2011

多分私はその質問を誤解しています。実際、私は間違いなくそうだと思います。
jscs 2011

1
またfName、ファイルが残っていても、何らかの理由で開くことができないファイルの名前である可能性もあります。たとえば、ディレクトリである場合や、実行中のプロセスによる読み取りを許可する権限がない場合などです。
直感的な2011

4
「ifexists(file):open(file)」メソッドは、ファイルが存在することを確認した後、開く前にファイルが削除される可能性があるため、失敗する可能性があります。または、ロックされているか、読み取り権限がないか、読み取りできないタイプのオブジェクト(ディレクトリなど)であるか、テープにアーカイブされていてテープが利用できないか、ディスクエラーが発生している可能性がありますファイルを開こうとしている、または...
Gabe 2011

64

これはどう:

try:
    f = open(fname, 'rb')
except OSError:
    print "Could not open/read file:", fname
    sys.exit()

with f:
    reader = csv.reader(f)
    for row in reader:
        pass #do stuff here

10
これに関する唯一の問題は、ファイルがwithブロックの外側で開かれることです。したがってtry、呼び出しを含むブロックopenwithステートメントの間に例外が発生した場合、ファイルは閉じられません。この場合、物事が非常に単純である場合、それは明らかな問題ではありませんが、コードをリファクタリングまたはその他の方法で変更するときに危険をもたらす可能性があります。そうは言っても、これを行うためのより良い方法はないと思います(元のバージョン以外)。
直感的な2011

2
@intuited:その通りです。実際、OPに対する最終的な答えはおそらく次のとおりです。いいえ、それを行った方法は正しい方法です。
jscs 2011

1
FileNotFoundError.mro() であり[<class 'FileNotFoundError'>, <class 'OSError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>]IOError.mro()です[<class 'OSError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>]。どちらかOSErrorまたは Exception代わりに使用するのはどうですか?`` `
hotohoto

1
@hotohoto:いい考えです。よくわかりません-おそらく2011年以降、この点で例外階層が変更されていますが、とにかくあなたの提案はより包括的です。
TimPietzcker19年

16

これが読み取り/書き込みの例です。withステートメントは、例外がスローされたかどうかに関係なく、close()ステートメントがファイルオブジェクトによって呼び出されることを保証します。 http://effbot.org/zone/python-with-statement.htm

import sys

fIn = 'symbolsIn.csv'
fOut = 'symbolsOut.csv'

try:
   with open(fIn, 'r') as f:
      file_content = f.read()
      print "read file " + fIn
   if not file_content:
      print "no data in file " + fIn
      file_content = "name,phone,address\n"
   with open(fOut, 'w') as dest:
      dest.write(file_content)
      print "wrote file " + fOut
except IOError as e:
   print "I/O error({0}): {1}".format(e.errno, e.strerror)
except: #handle other exceptions such as attribute errors
   print "Unexpected error:", sys.exc_info()[0]
print "done"

この場合、IOErrorは明らかですが、コードカバレッジの観点から一般的な例外が発生するのはいつですか。一般的な例外を生成するためのテストケースを作成するにはどうすればよいですか。
Mian Asbat Ahmad

0
fname = 'filenotfound.txt'
try:
    f = open(fname, 'rb')
except FileNotFoundError:
    print("file {} does not exist".format(fname))

file filenotfound.txt does not exist

例外FileNotFoundErrorファイルまたはディレクトリが要求されたが、存在しない場合に発生します。errnoENOENTに対応します。

https://docs.python.org/3/library/exceptions.html
この例外はPython2には存在しません。


1
このコードは質問に答えることができますが、問題を解決する方法や理由に関する追加のコンテキストを提供すると、回答の長期的な価値が向上します。
ドナルドダック

-12

@Joshの例に追加します。

fName = [FILE TO OPEN]
if os.path.exists(fName):
    with open(fName, 'rb') as f:
        #add you code to handle the file contents here.
elif IOError:
    print "Unable to open file: "+str(fName)

この方法でファイルを開こうとすることができますが、ファイルが存在しない場合(IOErrorが発生する場合)、ユーザーに警告してください。


問題が発生していません。構文が正しくない場合、実行時に構文エラーが発生します。
ザックブラウン

7
構文エラーでbool(IOError)Trueありifませんが、単純であり、例外をキャッチしません。

8
>>> if IOError: print "That's not an exception handler"
jscs 2011

3
@JoshCaswellは正しいです。IOErrorはTrueと評価されます。docs.python.org/2.4/lib/truth.html
hecvd
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.