在Python 3中逐行读取文件时捕获异常

时间:2017-11-23 10:10:03

标签: python python-3.x exception io

请考虑以下代码:

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

在Python 3中,解释器尝试解码它读取的字符串,这可能会导致像UnicodeDecodeError这样的异常。这些当然可以在整个循环中用try ... except块来捕获,但我想在每个行上处理它们。

问题:有没有办法直接捕获并处理每行读取的异常?希望没有改变过多迭代文件的简单语法?

4 个答案:

答案 0 :(得分:6)

Pythonic方法可能是使用codecs.register_error_handler('special', handler)注册错误处理程序并在open函数中声明它:

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

如果存在违规行,handler将使用UnicodeDecodeError进行调用,并且能够返回替换字符串或重新引发错误。

如果您想要更明显的处理,另一种方法是以二进制模式打开文件并明确解码每一行:

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

答案 1 :(得分:5)

您可以自己在文件迭代器上调用for而不是使用next循环,而是手动捕获StopIteration

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

答案 2 :(得分:2)

基于@SergeBallesta的答案。这是最简单的方法。

使用codecs.open(..., errors='your choice')代替open()。它可以为您处理Unicode错误。

list of error handler names包括

'replace':“用合适的替换标记替换; Python将使用官方的U + FFFD REPLACEMENT CHARACTER进行解码时使用内置编解码器,并在编码时使用'?””

应处理该错误,并在文本中添加标记“此处存在无效内容”。

import codecs

# ...

# instead of open('filename.txt'), do:
with codecs.open('filename.txt', 'rb', 'utf-8', errors='replace') as f:
    for line in f:
        # ....

答案 3 :(得分:-1)

将try-except catch放在for循环中,如下所示:

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