json.dumps(pickle.dumps(u'å'))引发UnicodeDecodeError

时间:2010-10-08 23:49:28

标签: python json pickle

这是一个错误吗?

>>> import json
>>> import cPickle
>>> json.dumps(cPickle.dumps(u'å'))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/json/__init__.py", line 230, in dumps
    return _default_encoder.encode(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/json/encoder.py", line 361, in encode
    return encode_basestring_ascii(o)
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 1-3: invalid data

3 个答案:

答案 0 :(得分:5)

json模块期望字符串对文本进行编码。腌制数据不是文本,它是8位二进制文​​件。

一个简单的解决方法,如果你真的需要通过JSON发送pickle数据,那就是使用base64:

j = json.dumps(base64.b64encode(cPickle.dumps(u'å')))
cPickle.loads(base64.b64decode(json.loads(j)))

请注意,这显然是一个Python错误。协议版本0 显式记录为ASCII,但是作为非ASCII字节\xe5发送,而不是将其编码为"\u00E5"。上游报告了此错误 - 并且在没有修复错误的情况下关闭了故障单。 http://bugs.python.org/issue2980

答案 1 :(得分:1)

可能是泡菜中的一个错误。我的python文档说(对于使用过的pickle格式):Protocol version 0 is the original ASCII protocol and is backwards compatible with earlier versions of Python. [...] If a protocol is not specified, protocol 0 is used.


>>> cPickle.dumps(u'å').decode('ascii')
Traceback (most recent call last):
  File "", line 1, in 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 1: ordinal not in range(128)

没有ASCII

并且,不知道它是否相关,甚至是一个问题:

 
>>> cPickle.dumps(u'å') == pickle.dumps(u'å')
False

答案 2 :(得分:0)

我正在使用Python2.6,您的代码运行时没有任何错误。

In [1]: import json

In [2]: import cPickle

In [3]: json.dumps(cPickle.dumps(u'å'))
Out[3]: '"V\\u00e5\\np1\\n."'

BTW,你的系统默认编码是什么,在我的例子中,它是

In [6]: sys.getdefaultencoding()
Out[6]: 'ascii'