Python读取非ascii文本文件

Pau*_*rtz 2 python utf-8

我正在尝试加载一个文本文件,其中包含一些德语字母

content=open("file.txt","r").read() 
Run Code Online (Sandbox Code Playgroud)

这会导致此错误消息

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 26: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)

如果我修改文件只包含ASCII字符,一切都按预期工作.

好好用

content=open("file.txt","rb").read() 
Run Code Online (Sandbox Code Playgroud)

要么

content=open("file.txt","r",encoding="utf-8").read()
Run Code Online (Sandbox Code Playgroud)

都做好了.

为什么可以用"二进制"模式读取并获得与utf-8编码相同的结果?

小智 5

在Python 3中,使用'r'模式而不指定编码只使用默认编码,在本例中为ASCII.使用'rb'模式将文件作为字节读取,并且不会尝试将其解释为字符串.


jed*_*rds 5

ASCII 仅限于 [0,128) 范围内的字符。如果您尝试解码超出该范围的字节,则会出现该错误。

\n\n

当您以字节形式读取字符串时,您将字符的可接受范围“扩大”到 [0,256)。所以你的 \\0xc3 字符\xc3\x83现在可以正确读取。但尽管它看起来有效,但它仍然不“正确”。

\n\n

如果您的字符串确实是 unicode 编码的,则存在其中包含多字节字符的可能性,即其字节表示实际上跨越多个字节的字符。

\n\n

在这种情况下,将文件读取为字节字符串与正确解码它之间的差异将非常明显。

\n\n

像这样的字符:\xc4\x8d

\n\n

将被读入两个字节,但正确解码后,将是一个字符:

\n\n
bytes = bytes(\'\xc4\x8d\', encoding=\'utf-8\')\n\nprint(len(bytes))                   # 2\nprint(len(bytes.decode(\'utf-8\')))   # 1\n
Run Code Online (Sandbox Code Playgroud)\n