2017-11-23 3 views
4

に行毎にファイルを読み取り中:Pythonの3ではキャッチ例外次のコードを検討のPython 3

with open('file.txt', 'r') as f: 
    for line in f: 
     print(line) 

を、インタプリタはUnicodeDecodeErrorのような例外につながるかもしれない、それは読み込み、文字列を、復号を試みます。これらはもちろんループ全体でブロックtry ... exceptで捕まえることができますが、私はそれらを1行単位で処理したいと思います。

質問:読み取られた各行の例外を直接キャッチして処理する方法はありますか?うまくいけば、あまりにも多くのファイルを反復処理の単純な構文を変更することなく?

+0

オープン後「の行の前に試みを入れていない理由f "で?? – ddor254

+0

申し訳ありませんが、私がここで何をしているのか明確にしていない場合は、その行のいずれかが例外になってもファイルを読むことができます。 – piripiri

+2

[開くには 'errors' argを指定できます](https://docs.python.org/3/library/functions.html#open)。データが本当に悪い場合は、バイナリモードで開いて、各行を明示的にデコードする必要がありますが、それは遅いです。 –

答えて

4

Python的な方法は、codecs.register_error_handler('special', handler)とエラーハンドラを登録し、open関数でそれを宣言するために、おそらくです:

with open('file.txt', 'r', error='special') as f: 
    ... 

このように違反行がある場合、handlerUnicodeDecodeErrorで呼び出され、置換文字列oを返すことができますrエラーを再発生させます。

あなたがより明らかに処理をしたい場合は、別の方法は、バイナリモードでファイルを開いて、明示的に各ラインをデコードするために、次のようになります。

with open('file.txt', 'rb') as f: 
    for bline in f: 
     try: 
      line = bline.decode() 
      print(line) 
     except UnicodeDecodeError as e: 
      # process error 
4

forループを使用する代わりに、ファイルイテレータでnextを呼び出してStopIterationを手動でキャッチすることができます。

with open('file.txt', 'r') as f: 
    while True: 
     try: 
      line = next(f) 
      # code 
     except StopIteration: 
      break 
     except UnicodeDecodeError: 
      # code 
+0

Pythonは(バッファ内の)ブロックで自由にデコードすることができますただ一つの行をスキップします。 –

+0

@MartijnPieters興味深い、それを知らなかった。 – timgeb

-1

置きますのtry-除くループのため、そのような内部のキャッチ:

with open('file.txt', 'r') as f: 
    for line in f: 
     try: 
     print(line) 
     except: 
     print("uh oh") 
     # continue 
+1

これはおそらく 'for:'の 'for line:'であり、それを引き起こします。 –

+1

'for'ループは' f .__ next__'を呼び出す原因ですので、エラーが発生します。私たちがループボディの中にいるのは遅すぎます。 – timgeb

+1

ああ、つまらない。その場合@timgebで提案された解決策が好きです。 – datadavis2

関連する問題