【问题标题】:When does Python decode a byte string while reading a file?Python 在读取文件时何时解码字节字符串?
【发布时间】:2016-05-11 10:50:57
【问题描述】:

我有一个带有关键字的文本文件,我使用了

with open('filename.txt','r') as file:
    list_of_words = [x.strip('\n') for x in file.readlines()

我得到一个: UnicodeDecodeError : 'ascii' 编解码器无法解码位置 5595 中的字节 0xc4:序数不在范围内 (128) 在第 2 行

我理解错误。我不明白为什么它在第 2 行。

根据 python 文档:https://docs.python.org/3/library/functions.html#open

在文本模式下(默认,或者当模式中包含 't' 时 参数),文件的内容以 str 的形式返回,字节 已使用平台相关编码或使用 指定的编码(如果给定)。

这意味着在打开文件时,解码过程在打开文件时发生,并在'file'变量中返回。

那么为什么我会在第 2 行得到错误呢?

【问题讨论】:

  • 为什么会发生在第 1 行?只有在实际读取数据时才会发生任何解码。只有在第 2 行,您才从文件中读取数据。

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


【解决方案1】:

对于从文件对象读取的实际过程,您似乎对 open() 调用返回的 file object 感到困惑。

Python 在您阅读文件时解码文件的内容。打开文件对象不会从文件中读取任何数据,它只是创建一个文件对象。此时没有从文件中读取任何数据,没有可供 Python 处理的字节尚未

在第 2 行中,您实际上是使用file.readlines() 方法从文件中读取那个方法告诉文件对象从文件系统中获取数据(字节)并解码这些字节。只有那么,Python 才能知道数据实际上不能被解码为 ASCII。

【讨论】:

    【解决方案2】:

    打开文件实际上并不检查内容。只有当部分文件数据通过其执行读取的几种方法之一返回时,才能对内容进行解码。

    【讨论】:

    • 所以你的意思是“文件”变量的类型仍然是字节。就是调用file.readlines()的时候,数据被解码了吗?
    • “文件”变量的类型是file
    • @ChintanShah:不,文件对象就是文件对象。解码不适用于文件对象,仅适用于从中读取的数据。
    • 谢谢。我现在明白了。所以发生的事情是 open 返回一个文件指针,然后当我们读取内容时,python 尝试使用默认编解码器对其进行解码。我说的对吗?
    • @ChintanShah:在 Python 中一切都是对象open() 返回一个文件对象。请参阅io module documentation 以了解返回的对象类型以及可用的方法。
    【解决方案3】:

    您不会立即收到错误消息,因为文件刚刚打开,而不是从第 1 行读取。打开文件只涉及从操作系统获取文件的句柄 - 没有内容被读取。

    仅当您调用readlinesread、遍历文件或以其他方式从文件中读取您实际获取的内容时,最初以字节为单位。然后对这些字节进行解码,然后才发现在指定的编码中不是有效的。

    如果你没有指定编码,pythonguesses it from the operating system configuration:

    encoding 是用于解码或编码 (...) 的编码名称。默认编码取决于平台(无论 locale.getpreferredencoding() 返回什么)

    您的系统上locale.getpreferredencoding() 似乎返回 ASCII,并且文件未以 ASCII 编码。

    只需指定正确的编码:

    with open('filename.txt', 'r', encoding='utf-8') as file:
        list_of_words = [line.strip('\n') for line in file]
    

    【讨论】:

    • OP似乎认为打开文件的行为也涉及解码。他们不会对编码错误的原因感到困惑,只是对在哪里进行解码感到困惑。
    • 谢谢,我明白了。现在我还有第二个问题,我的 locale.getpreferredencoding() 返回 'UTF-8'。即便如此,我仍然收到错误消息说“ascii”无法解码。这是为什么呢?
    • @ChintanShah 这真的很奇怪。如果您将编码指定为open,您会得到同样的错误吗?
    • 不知何故我无法重现该错误。无论哪种方式,问题仍然存在,它应该采用 utf-8 作为编解码器..
    【解决方案4】:

    实际上,这只是文档中措辞不佳的解释。 Open 函数不读取任何内容,它只返回从 OS 传递给它的具有指定模式和编码的文件句柄。

    【讨论】:

    • 我不同意这里有任何措辞不当的解释。缺少的是对文件对象如何生成文件内容的理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    • 2020-06-09
    • 1970-01-01
    相关资源
    最近更新 更多