【问题标题】:UnicodeDecodeError: 'utf8' codec can't decode byte inside a dictionaryUnicodeDecodeError:“utf8”编解码器无法解码字典中的字节
【发布时间】:2016-05-07 06:53:12
【问题描述】:

这里已经有类似的问题了。在我看来,以下问题是不同的,因为我有字典而不是字符串。

所以,我有一个字典:result_dict。此字典中的某些值可能包含 ü、ä、ß 等。

当我尝试使用以下命令转储此字典时:

result_dict_dumped = json.dumps(result_dict)

我收到此错误消息:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xfc in position 9: invalid start byte

有没有机会在不获取字典中的每个值并对其进行编码的情况下解决这个问题?

这是一个小的示例字典:

{
    'POSSIBLE_DATACENTER': 'tt@4', 
    'CPU_COUNT': None, 
    'DESCRIPTION': 'Test-DC f\xfcr tbc'
}

f\xfcr 实际上是für

【问题讨论】:

  • 您使用的是哪个 Python 版本? Python 3 中的 Unicode 处理与 Python 2 中的处理方式有些不同。您应该发布一个字典的小示例。
  • 我使用的是 Python 2.7。字典内容示例:{'POSSIBLE_DATACENTER': 'tt@4', 'CPU_COUNT': None, 'DESCRIPTION': 'Test-DC f\xfcr tbc'}。 f\xfcr 实际上是“für”。
  • json 是基于文本的格式,它不能用于表示任意字节序列。您的 dict 数据使用什么编码?
  • 不知道dict数据的编码格式
  • @TomDalton:我的猜测(根据示例数据)是编码是 latin1。

标签: python json python-2.7 dictionary


【解决方案1】:

JSON 是一种基于文本的格式,它不能用于表示任意字节序列。您的 dict 数据使用什么编码 - 字节 0xfc 不是有效的 1 字节 utf-8 字符。

在尝试对其进行 json 编码之前,您可能需要解码 dict 的内容(从当前存储的任何编码)。

编辑:您的 dict 数据编码可能是以下任何一种编码:

>>> x = b"\xfc"
>>> print x.decode("latin-1")
ü
>>> print x.decode("cp1252")
ü

>>> json.dumps(x.decode("latin-1"))
'"\\u00fc"'

您还调用告诉 json 编码器字符串与 utf-8 的编码不同 - 这可能是您想要做的,只要您的 dict 中的每个 str 都采用这种编码:

>>> json.dumps(b"\xfc", encoding="latin-1")
'"\\u00fc"'

【讨论】:

  • "latin-1" 是"ISO-8859-1"的别名
  • 好的。我是否正确理解我必须遍历我的 dict 的内容并以正确的格式对所有内容进行编码并将其放入新的 dict 中?
  • 在底部查看我的最后一次编辑 - 您可以将编解码器名称传递给 json.dump,它会为您执行此操作 - 只要输入文档中的每个字符串都采用该编码!跨度>
  • 有效!!!谢谢!!!! json.dumps(result_dict, encoding="latin-1") 完美运行!
【解决方案2】:

听起来你在运行python2——你需要使用decode方法...

小例子 - 对不起使用你的字母......

import pprint
gstr_in_bytes=bytearray(b'ü'+b'ä'+b'ß')
type(gstr_in_bytes)

print("Data looks like this")
pprint.pprint(gstr_in_bytes)
print("String in utf8 is %s"%gstr_in_bytes.decode('utf-8'))

你应该看到

Data looks like this
bytearray(b'\xc3\xbc\xc3\xa4\xc3\x9f')
String in utf8 is üäß

【讨论】:

    【解决方案3】:

    Tom 已经回答了您的问题,但您可能会发现这段代码的输出很有趣。请注意,我的终端配置为使用 UTF-8 编码。

    import json
    
    d = {
        'POSSIBLE_DATACENTER': 'tt@4', 
        'CPU_COUNT': None, 
        'DESCRIPTION': 'Test-DC f\xfcr tbc'
    }
    
    def show_dict(d):
        for k, v in d.iteritems():
            print k, v
    
    print '*** Original ***'
    show_dict(d)
    
    print '\n*** Decoded from latin1 ***'
    s = json.dumps(d, encoding='latin1', indent=4)
    print s
    
    newd = json.loads(s)
    print '\n*** Reloaded ***'
    show_dict(newd)
    
    print '\n*** new dump ***'
    print json.dumps(newd, indent=4)
    

    输出

    *** Original ***
    POSSIBLE_DATACENTER tt@4
    CPU_COUNT None
    DESCRIPTION Test-DC f�r tbc
    
    *** Decoded from latin1 ***
    {
        "POSSIBLE_DATACENTER": "tt@4", 
        "CPU_COUNT": null, 
        "DESCRIPTION": "Test-DC f\u00fcr tbc"
    }
    
    *** Reloaded ***
    POSSIBLE_DATACENTER tt@4
    CPU_COUNT None
    DESCRIPTION Test-DC für tbc
    
    *** new dump ***
    {
        "POSSIBLE_DATACENTER": "tt@4", 
        "CPU_COUNT": null, 
        "DESCRIPTION": "Test-DC f\u00fcr tbc"
    }
    

    这篇文章可能对您有所帮助:Pragmatic Unicode,由 SO 资深人士 Ned Batchelder 撰写。

    【讨论】:

      猜你喜欢
      • 2016-08-03
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-20
      • 1970-01-01
      相关资源
      最近更新 更多