【问题标题】:ascii decoding error in an ascii file (Python 3.5)ascii 文件中的 ascii 解码错误(Python 3.5)
【发布时间】:2017-01-14 13:46:41
【问题描述】:

我有一个文本文件(通过在 linux 中重定向 find 命令的输出创建)。该文件的前 4 行如下所示:

/home/uujjwal/datasets/pedestrian/INRIAPerson/Train/pos/person_299.png
/home/uujjwal/datasets/pedestrian/INRIAPerson/Train/pos/crop001540.png
/home/uujjwal/datasets/pedestrian/INRIAPerson/Train/pos/crop001044.png
/home/uujjwal/datasets/pedestrian/INRIAPerson/Train/pos/person_195.png

我使用以下代码在 Python 2.7 中将其作为完整字符串读取:

fid = open('filelist.txt', 'r').read() # Successful

当我尝试在 python 3.5 中执行相同操作时,我收到以下错误:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf4 in position 141: invalid continuation byte

我意识到 python 3.5 和 2.7 之间的差异,并尝试指定 ascii 编码。我通过使用chardet 包确定ascii 编码如下(使用其命令行工具):

 [uujjwal@rotanev pos]$ chardetect /home/uujjwal/datasets/pedestrian/INRIAPerson/Train/pos/filelist.txt
/home/uujjwal/datasets/pedestrian/INRIAPerson/Train/pos/filelist.txt: ascii with confidence 1.0

因此我做了以下事情:

fstr = open(annotation_file, 'r', encoding='ascii').read() #Failure

这给出了以下错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xf4 in position 141: ordinal not in range(128)

我想明白:

  1. 为什么会弹出这些错误?
  2. 我解决问题的步骤有什么问题。

注意:我没有以任何方式手动修改文本文件。

附录

  1. 我检查了文件的全部内容。它有字母 a-z、A-Z、0-9(所有的 ASCII 值都是众所周知的)正斜杠 (/)(扩展 ASCII 值为 47)和下划线 (_)(扩展 ASCII 值为95)以及一个点 (.)(扩展的 ASCII 值 46)。它还具有换行符(** 10 的扩展 ASCII 值**)。文件中没有其他字符。

  2. 字节 0xf4 对应 244 的扩展 ASCII(段落符号)。这是无法存在的,因为文件是通过重定向find 命令的输出创建的。

【问题讨论】:

  • 那么您的文件不包含 ASCII。在 Python 2 中,您所做的只是读取字节,不进行解码。
  • Chardet 可能是错误的;它使用启发式方法,并且并非万无一失
  • ASCII 只有 0 到 127。
  • with open('filelist.txt', 'rb') as f: print(f.read(150)[130:]) 输出什么?这为我们提供了解码错误周围 20 个字节的上下文。
  • @Ujjwal:如果尚未完成,请考虑对答案进行投票。

标签: python python-2.7 python-3.x


【解决方案1】:

文件不是 ASCII 编码的。 Chardet 使用启发式算法并且没有测试整个文件,这里弄错了。它也不是 UTF-8,由另一个错误证明。

Chardet 无法始终分辨出它在看什么:

>>> chardet.detect((('This mostly ASCII, with a hidden surprise' * 20) + 'hellø').encode('utf8'))
{'encoding': 'ISO-8859-2', 'confidence': 0.7225312698370376}

ø 仅编码为两个字节:

>>> 'ø'.encode('utf8')
b'\xc3\xb8'

这些信息不足以让 chardet 做出正确的决定。

使用不同的编解码器打开文件。究竟是什么编解码器很难说;在 Latin-1 和 Windows 代码页 1252 中,0xF4 是 ô 字符,它看起来并不适合您显示的最小数据(位置 141 将在前 4 行内)。

请注意,在 Python 2 中,您实际上只读取文件的二进制内容,而没有将数据解码为 Unicode 文本,这就是您不会在此处收到错误的原因。

请注意,没有“扩展 ASCII”之类的东西。 exists 这个词是假的,没有 standard 具有该名称,并且用于几乎任何 8 位编解码器,它是 ASCII 的超集。一个字节值 0xF4 在不同的编解码器中表示不同的东西;在 IBM 775 codepage 中是 Paragraph (Pilcrow) symbol,在代码页 850、856、857 和 858 中也是如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-07
    • 2011-02-13
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 2017-10-19
    • 1970-01-01
    相关资源
    最近更新 更多