ASCII编解码器无法解码字节0xe9。

7

我已经做了一些研究并看到了一些解决方案,但是没有一个对我起作用。

Python - 'ascii'编解码器无法解码字节

这对我没有起作用。而且我知道0xe9是é字符。但我仍然无法弄清楚如何让它工作,这是我的代码:

output_lines = ['<menu>', '<day name="monday">', '<meal name="BREAKFAST">', '<counter name="Entreé">', '<dish>', '<name icon1="Vegan" icon2="Mindful Item">', 'Cream of Wheat (Farina)','</name>', '</dish>', '</counter >', '</meal >', '</day >', '</menu >']
output_string = '\n'.join([line.encode("utf-8") for line in output_lines])

这给我带来了错误:ascii编码无法解码字节0xe9

我已经尝试过解码,也尝试过替换“é”,但似乎都无法解决问题。


2
您的代码示例无效,无法重现问题;output_lines为空,因此您的循环不会执行任何操作。您的错误表明在编码时存在解码错误,这通常表示您正在尝试对已经编码的数据进行编码。 - Martijn Pieters
@MartijnPieters 对不起,我没有展示我的示例代码是完整的,但它已经填充了。我会把它添加到问题中。 - iqueqiorio
1
这仍然不是你实际的 output_lines ... 你能在尝试创建 output_string 之前打印 output_lines 吗? - Joran Beasley
你的数据已经编码,为什么还觉得需要再次编码呢? - Martijn Pieters
@iqueqiorio,不幸的是,您做得不仅仅是缩短它... - Joran Beasley
显示剩余3条评论
4个回答

5

您正在尝试对字节串进行编码:

>>> '<counter name="Entreé">'.encode('utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 20: ordinal not in range(128)

Python试图提供帮助,您只能将Unicode字符串编码为字节,所以 Python 首先会隐式地 解码,使用默认的编码方式。

解决方法是不要对已经编码的数据进行编码,或者在尝试重新编码之前使用适当的编解码器进行解码,如果数据是用与您所需不同的编解码器进行编码的。

如果您有一些Unicode和字节串值的混合体,请仅对字节串进行解码或仅对Unicode值进行编码;尽量避免混合使用这两种类型。以下示例首先将字节串解码为Unicode:

def ensure_unicode(v):
    if isinstance(v, str):
        v = v.decode('utf8')
    return unicode(v)  # convert anything not a string to unicode too

output_string = u'\n'.join([ensure_unicode(line) for line in output_lines])

1
@iqueqiorio:你的列表里有Unicode和字节字符串的混合吗? - Martijn Pieters
肯定不会出现 UnicodeDecodeError: ascii codec cannot ... - Joran Beasley
我收到了“Unicode解码:'utf8'编解码器无法解码字节”的错误信息。 - iqueqiorio
1
@JoranBeasley:或者cp1252;两者都不会“失败”,但如果选择的编解码器不正确,可能无法产生可读的输出。 - Martijn Pieters
1
@iqueqiorio:那么Web服务器可以为您提供编解码器,或者XML格式本身可以在元数据中包含编解码器。 - Martijn Pieters
显示剩余12条评论

4

这个问题的一个简单示例是:

>>> '\xe9'.encode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)

\xe9不是ASCII字符,这意味着您的字符串已经编码。您需要将其解码为Python的Unicode,然后再次使用所需的序列化格式进行编码。

由于我不知道您的字符串来自哪里,所以我查看了Python codecs,从西欧选择了一些内容并进行了尝试:

>>> '\xe9'.decode('cp1252')
u'\xe9'
>>> u'\xe9'.encode('utf-8')
'\xc3\xa9'
>>> 

如果您知道文件使用的确切编码方式,那么您就会更容易地进行操作。


2

编码 = 将Unicode字符串转换为字节串

解码 = 将字节串转换为Unicode

由于你已经有了一个字节串,所以需要解码将其转换为Unicode实例(假设这确实是你要做的)

output_string = '\n'.join(output_lines)
print output_string.decode("latin1")  #now this returns unicode

0

根据您想要对行执行的操作,您可以在此处进行不同的工作。如果您只想像通常的控制台一样打印,使用utf8编码,您无需自己执行此操作,因为您的字符串格式不是unicode

>>> output_string = '\n'.join(output_lines)
>>> print output_string
<menu>
<day name="monday">
<meal name="BREAKFAST">
<counter name="Entreé">
<dish>
<name icon1="Vegan" icon2="Mindful Item">
Cream of Wheat (Farina)
</name>
</dish>
</counter >
</meal >
</day >
</menu > 

但是如果你想要写入文件,你可以使用codecs模块:

import codecs
f= codecs.open('out_file','w',encoding='utf8')

或者只需使用 "\n".join(output_lines) - Joran Beasley
@JoranBeasley 是的!对不起我错过了你的回答! - Mazdak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接