【问题标题】:Python 2.7.6 + unicode_literals - UnicodeDecodeError: 'ascii' codec can't decode bytePython 2.7.6 + unicode_literals - UnicodeDecodeError: 'ascii' codec can't decode byte
【发布时间】:2015-05-15 13:17:46
【问题描述】:

我正在尝试打印以下 unicode 字符串,但收到 UnicodeDecodeError: 'ascii' codec can't decode byte 错误。你能帮忙形成这个查询,以便它可以正确打印 unicode 字符串吗?

>>> from __future__ import unicode_literals
>>> ts='now'
>>> free_form_request='[EXID(이엑스아이디)] 위아래 (UP&DOWN) MV'
>>> nick='me'

>>> print('{ts}: free form request {free_form_request} requested from {nick}'.format(ts=ts,free_form_request=free_form_request.encode('utf-8'),nick=nick))

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xec in position 6: ordinal not in range(128)

非常感谢您!

【问题讨论】:

  • 试试ignoring the errorsfree_form_request.encode('utf-8', errors='ignore')
  • @PeterWood 这不起作用,在编码后解码字符串时会出现问题。请注意,由于 unicode_literals 导入,字符串已经是 unicode。
  • @ThomasOrozco 啊,我错过了。

标签: python python-2.7 unicode


【解决方案1】:

当你构造这个字符串时会发生以下情况:

'{ts}: free form request {free_form_request} requested from {nick}'.format(ts=ts,free_form_request=free_form_request.encode('utf-8'),nick=nick)
  1. free_form_requestencode-d 转换为字节字符串,使用utf-8 作为编码。这是因为utf-8 可以代表[EXID(이엑스아이디)] 위아래 (UP&amp;DOWN) MV
  2. 但是,格式字符串 ('{ts}: free form request {free_form_request} requested from {nick}') 是 unicode 字符串(因为导入了 from __future__ import unicode_literals)。
  3. 您不能使用 字节字符串 作为 unicode 字符串 的格式参数,因此 Python 会尝试 decode 在 1. 中创建的字节字符串来创建 unicode 字符串(作为格式参数有效)。
  4. Python 尝试使用默认编码ascii 进行decode-ing,但失败了,因为字节字符串是utf-8 字节字符串,其中包含在ascii 中没有意义的字节值.
  5. Python 抛出 UnicodeDecodeError

请注意,虽然代码显然在这里做了一些事情,但这实际上不会在 Python 3 上引发异常,而是会替换字节字符串的 reprrepr 是一个 unicode 字符串)。


要解决您的问题,只需将 unicode 字符串传递给 format

也就是说,不要执行步骤 1。将 free_form_request 编码为字节字符串:通过删除 .encode(...) 将其保留为 unicode 字符串:

'{ts}: free form request {free_form_request} requested from {nick}'.format(
    ts=ts, 
    free_form_request=free_form_request, 
    nick=nick)

请注意 Padraic Cunningham 在 cmets 中的回答。

【讨论】:

  • 我在一个更大的函数中有来自原始问题的代码块。事实证明,我导入的东西重写了打印功能,无法正确处理 unicode 字符串。不幸的是,我的解决方法是 encode('ascii', errors='ignore') 并删除 unicode 字符并处理它。
  • @PrestonConnors 然后你应该编码格式化的字符串,而不是格式参数。只需:print('...'.format(...).encode('utf-8'))
  • 虽然原始代码不会在 Python 3 上抛出异常,但 Python 3 不会将字节字符串隐式解码回 Unicode(步骤 3),因此打印的是 repr 的字节串编码。要在 Python 3 上正常工作,encode 仍然必须被删除。
猜你喜欢
  • 2018-07-29
  • 2013-03-16
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多