【问题标题】:how to skip enumerate encoding exception in python3?如何跳过python3中的枚举编码异常?
【发布时间】:2016-05-29 09:51:43
【问题描述】:

我制作了脚本并预处理了大型 csv 以导入数据库:

with open(sys.argv[1], encoding='utf-16') as _f:
    for i, line in enumerate(_f):
        try:
            .... some stuff with line ...
        except Exception as e:
            ...

但在某些时候它给了我enumerate 的例外:

...
  File "/Users/elajah/PycharmProjects/untitled1/importer.py", line 94, in main
    for i, line in enumerate(_f):
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/codecs.py", line 319, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/encodings/utf_16.py", line 69, in _buffer_decode
    return self.decoder(input, self.errors, final)
UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x00 in position 0: truncated data
...

如何跳过文件中的断行而不中断脚本流程?

【问题讨论】:

    标签: python-3.x codec


    【解决方案1】:

    您可以将参数errors="ignore" 传递给open,告诉Python 在读取文件时不关心编码错误。

    with open(sys.argv[1], errors="ignore") as _f:
    

    然而,这可能表现得很奇怪,因为它只会跳过无效字节,而不是无效字节出现的整行。

    如果您需要的行为是在解码出现任何问题时忽略整行,您最好以二进制模式读取文件并在您的 try/except 块内部尝试自己解码循环:

    with open(sys.argv[1], 'b') as _f:
        for i, line_bytes in enumerate(_f):
            try:
                line = line_bytes.decode('utf-16')
                # do some stuff with line ...
            except UnicodeDecodeError:
                pass
    

    最后一个想法是修复文件数据的任何问题,这样您在读取文件时就不会出现解码错误。但谁知道那是多么容易。如果您从其他地方获取文件,超出您的控制范围,则可能没有任何实用的方法可以提前修复它。

    【讨论】:

      【解决方案2】:

      您通过捕获异常而无所作为来忽略异常

          try:
              .... some stuff with line ...
          except UnicodeDecodeError as e:
              pass
      

      但如果这真的是你想要的,那将取决于情况。

      您可以在堆栈跟踪的最后一行找到异常的名称

      UnicodeDecodeError: 'utf-16-le' 编解码器无法解码位置 0 中的字节 0x00:截断数据

      【讨论】:

      • 谢谢我已经尝试过了,但在这种情况下,它发生在 enumerate 函数调用期间,我看到的唯一可能的解决方案是不使用它......
      • 您可以将整个for ... in enumarate() 块放入try: 块中。但在您的 importer.py 脚本中使用 try: 可能会更好,因为发生初始错误,并尝试修复那里的错误。
      猜你喜欢
      • 2011-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多