【问题标题】:ascii codec cant decode byte 0xe9ascii 编解码器无法解码字节 0xe9
【发布时间】:2015-05-10 22:33:24
【问题描述】:

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

Python - 'ascii' codec can't decode byte

这对我不起作用。而且我知道 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 codec cant decode byte 0xe9

我已经尝试解码,我尝试替换“é”,但似乎也无法让它工作。

【问题讨论】:

  • 您的代码示例无效,不会重现问题; output_lines 是空的,所以你的循环不会做任何事情。您的错误表明您在编码时遇到解码错误,这通常表明您正在尝试对已经编码的数据进行编码。
  • @MartijnPieters 抱歉,我的示例代码中没有显示它已满,但已满。我将把它添加到问题中
  • 这仍然不是您的实际output_lines ...当然...您可以在尝试创建output_string之前print output_lines
  • @JoranBeasley 是的,但是 output_lines 必须更长,所以我缩短了它
  • 你的数据已经编码,为什么你觉得需要再次编码?

标签: python unicode encoding utf-8 decode


【解决方案1】:

您正在尝试编码字节串:

>>> '<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 进行隐式 decodes 编码,使用默认编码。

解决方案是不对已经编码的数据进行编码,或者如果数据被编码为与您需要的不同的编解码器,则在再次尝试编码之前先使用合适的编解码器进行解码。

如果你有 unicode 和 bytestring 值的混合,只解码 bytestrings 或只编码 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])

【讨论】:

  • afaik 这也表明他正在使用 python2x ...因为在 3x 中它不再尝试隐式转换内容并且您会得到更清晰的错误(+1 ofc)
  • @JoranBeasley 和 Martijn 当我将其更改为 output_string = '\n'.join([line for line in output_lines]) 时,我仍然遇到同样的错误?
  • @iqueqiorio:您的列表中是否有 混合 Unicode 和字节字符串?
  • @JoranBeasley: 或 cp1252;两者都不会失败,但如果编解码器错误,则可能不会产生可读的输出。
  • @iqueqiorio:那么 Web 服务器可以为您提供编解码器,或者 XML 格式本身可以将编解码器包含在元数据中。
【解决方案2】:

问题的一个简单例子是:

>>> '\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'
>>> 

如果您确切知道文件来自哪个编码,那么您将获得最好的运气。

【讨论】:

    【解决方案3】:

    encode = 将 unicode 字符串转换为字节串

    decode = 将字节串转为 unicode

    因为你已经有一个字节串,你需要解码以使其成为一个 unicode 实例(假设这实际上是你想要做的)

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

    【讨论】:

      【解决方案4】:

      根据你想对你的行做什么,你可以在这里做不同的工作,如果你只是想在领事中打印,通常领事使用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)
      • @JoranBeasley 是的!对不起,我错过了你的答案!
      猜你喜欢
      • 1970-01-01
      • 2013-08-17
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      • 2014-04-09
      • 2018-08-02
      • 2013-09-23
      相关资源
      最近更新 更多