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

Python json.dumps(pickle.dumps(u';å;';)引发UnicodeDecodeError,python,json,pickle,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/Vers

这是虫子吗

>>> 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
导入json >>>进口包装 >>>json.dumps(cPickle.dumps(u'å')) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/json/_init__.py”,第230行,转储 返回默认编码器编码(obj) encode中的文件“/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/json/encoder.py”,第361行 返回编码\基串\ ascii(o) UnicodeDecodeError:“utf8”编解码器无法解码位置1-3中的字节:无效数据
json模块希望字符串编码文本。pickle数据不是文本,而是8位二进制

如果确实需要通过JSON发送pickled数据,一个简单的解决方法是使用base64:

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

请注意,这显然是一个Python错误。协议版本0明确记录为ASCII,但å作为非ASCII字节
\xe5
发送,而不是将其编码为
“\u00E5”
。这个错误是在上游报告的——并且在没有修复错误的情况下关闭了票据

可能是泡菜里的虫子。我的python文档说(对于使用的pickle格式):
协议版本0是原始的ASCII协议,与python的早期版本向后兼容。[…]如果未指定协议,则使用协议0。


>>> 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

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

In [1]: import json

In [2]: import cPickle

In [3]: json.dumps(cPickle.dumps(u'å'))
Out[3]: '"V\\u00e5\\np1\\n."'
顺便问一下,你的系统默认编码是什么,在我的情况下,它是

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

2.6.4中的错误确实发生在我身上。什么补丁版本?也许在以后的2.6版本中,关闭并假装它不是一个bug的bug被修复了。@Glenn Maynard:我使用的是2.6.5:PAlso发生在2.6.6中,不管sys.getdefaultencoding如何
cPickle.dumps(u'å')
返回
'V\xe5\n.
,而不是
'V\\u00e5\n.
。我很好奇为什么您返回的是后者(这是正确的输出:完全是ASCII);您的cPickle模块与其他所有模块都有相同的错误。请注意,我无法解码以上数据<该字符串上的code>json.loads()会生成一个Unicode字符串,该字符串
cPickle.loads
会对(
参数1必须是字符串,而不是Unicode
)抛出错误。