UnicodeDecodeError:“ascii”编解码器无法解码位置 23 中的字节 0xc3:序数不在范围内(128)

Posted

技术标签:

【中文标题】UnicodeDecodeError:“ascii”编解码器无法解码位置 23 中的字节 0xc3:序数不在范围内(128)【英文标题】:UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 23: ordinal not in range(128) 【发布时间】:2014-08-19 22:55:12 【问题描述】:

当我尝试连接它时,当字段包含“ñ”或“´”时,我会收到 UnicodeDecodeError。如果包含 'ñ' 或 '´' 的字段是最后一个,我不会出错。

#...

nombre = fabrica
nombre = nombre.encode("utf-8") + '-' + sector.encode("utf-8")
nombre = nombre.encode("utf-8") + '-' + unidad.encode("utf-8")

#...

return nombre 

有什么想法吗?非常感谢!

【问题讨论】:

Python - 'ascii' codec can't decode byte的可能重复 【参考方案1】:

您正在编码为 UTF-8,然后 重新-编码为 UTF-8。 Python 只能在第一次 解码 为 Unicode 时执行此操作,但它必须使用默认的 ASCII 编解码器:

>>> u'ñ'
u'\xf1'
>>> u'ñ'.encode('utf8')
'\xc3\xb1'
>>> u'ñ'.encode('utf8').encode('utf8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

不要一直编码;将编码保留为 UTF-8 到最后可能的时刻。改为连接 Unicode 值。

您可以在此处使用str.join()(或者,更确切地说,unicode.join())将三个值用短划线连接起来:

nombre = u'-'.join(fabrica, sector, unidad)
return nombre.encode('utf-8')

但即使在这里编码也可能为时过早。

经验法则:在收到值的那一刻解码(如果不是 API 提供的 Unicode 值),仅在必须时进行编码(如果目标 API 不直接处理 Unicode 值)。

【讨论】:

我认为这里的经验法则是关键。它的措辞可以是——“仅在 API 边界上编码和解码,然后仅在你必须这样做时”。 感谢您的回答。正在与我认为是“简单”转换的东西撞在一起……你关于双重编码的注释是正确的。【参考方案2】:

当您收到UnicodeEncodeError 时,这意味着您在代码中的某处直接将字节字符串转换为 unicode 字符串。默认情况下,在 Python 2 中它使用 ascii 编码,在 Python3 中使用 utf8 编码(两者都可能失败,因为不是每个字节在任一编码中都有效)

为避免这种情况,您必须使用显式解码。

如果您的输入文件中可能有 2 种不同的编码,其中一种接受任何字节(例如 UTF8 和 Latin1),您可以尝试首先使用第一个转换字符串,如果发生 UnicodeDecodeError 则使用第二个。

def robust_decode(bs):
    '''Takes a byte string as param and convert it into a unicode one.
First tries UTF8, and fallback to Latin1 if it fails'''
    cr = None
    try:
        cr = bs.decode('utf8')
    except UnicodeDecodeError:
        cr = bs.decode('latin1')
    return cr

如果您不知道原始编码并且不关心非ascii字符,您可以将decode方法的可选errors参数设置为replace。任何有问题的字节都将被替换(来自标准库文档):

用合适的替换字符替换; Python 将使用官方的 U+FFFD REPLACEMENT CHARACTER 作为内置的 Unicode 编解码器进行解码和使用“?”进行编码。

bs.decode(errors='replace')

【讨论】:

这不是对当前问题的直接回答,而是对作为重复关闭的that one 的回答。至少它是相关的,因为 UnicodeDecodeError 并且搜索错误的用户会找到这个答案......【参考方案3】:

我在 python3 中执行时遇到了这个错误,我只需在 python2

中执行就可以运行相同的程序

【讨论】:

以上是关于UnicodeDecodeError:“ascii”编解码器无法解码位置 23 中的字节 0xc3:序数不在范围内(128)的主要内容,如果未能解决你的问题,请参考以下文章

UnicodeDecodeError: 'ascii' 编解码器无法在位置解码字节 0xec

Python/Flask:UnicodeDecodeError/UnicodeEncodeError:“ascii”编解码器无法解码/编码

UnicodeDecodeError:“ascii”编解码器无法解码位置 1 的字节 0xef

如何避免 Redshift Python UDF 出现 UnicodeDecodeError ascii 错误?

python2 当中 遇到 UnicodeDecodeError UnicodeDecodeError: 'ascii' codec can't decode byte 0xe

UnicodeDecodeError:'ascii'编解码器无法解码位置 284 中的字节 0x93:序数不在范围内(128)[重复]