0

json尝试使用 Python 2.7 (即:)将 dict 对象序列化为 json 字符串import json

Example:
json.dumps({
    'property1':        'A normal string',
    'pickled_property': \u0002]qu0000U\u0012
})

该对象中有一些字节字符串是使用“腌制”的数据cPickle,因此出于 json 的目的,它们基本上是随机字节字符串。我正在使用 django.utils simplejson,这很好用。但我最近在谷歌应用引擎上切换到 Python 2.7,他们似乎不再有 simplejson 可用。

现在我正在使用json,当它遇到不属于 UTF-8 的字节时会引发异常。我得到的错误是:

UnicodeDecodeError:“utf8”编解码器无法解码位置 0 的字节 0x80:无效的起始字节

如果它像调试可能那样打印出一串字符代码会很好,即:\u0002]q\u0000U\u001201. 但我真的不太关心它如何处理这些数据,只要它不抛出异常并继续序列化它确实识别的信息。

我怎样才能做到这一点?

谢谢!

4

1 回答 1

2

JSON 规范根据unicode 字符定义字符串。出于这个原因,json模块假定str它接收到的任何实例都包含编码的 unicode 文本。它将尝试将 UTF-8 作为其默认编码,当您的字符串输出pickle.dumps可能不是有效的 UTF-8 序列时,这会导致麻烦。

幸运的是,解决问题很容易。您只需要告诉json.dumps函数使用什么编码而不是 UTF-8。以下将起作用,即使my_bytestring不是有效的 UTF-8 文本:

import json, cPickle as pickle

my_data = ["some data", 1, 2, 3, 4]
my_bytestring = pickle.dumps(my_data, pickle.HIGHEST_PROTOCOL)
json_data = json.dumps(my_bytestring, encoding="latin-1")

我相信任何 8 位编码都可以代替latin-1此处使用的编码(请确保稍后使用相同的编码进行解码)。

当您想解开 JSON 编码数据时,您需要调用unicode.decode,因为json.loads总是将编码字符串作为unicode实例返回。因此,要从上面my_data恢复列表json_data,您需要以下代码:

my_unicode_data = json.loads(json_data)
my_new_bytestring = my_unicode_data.encode("latin-1")  # equal to my_bytestring
my_new_data = pickle.loads(my_new_bytestring)          # equal to my_data
于 2012-09-07T06:32:11.070 回答