json.dumps (pickle.dumps (u'å ')) вызывает UnicodeDecodeError - PullRequest
4 голосов
/ 09 октября 2010

Это ошибка?

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

6 голосов
/ 09 октября 2010

Модуль json ожидает строки для кодирования текста.Данные в маринованном виде - это не текст, а 8-разрядный двоичный файл.

Один простой обходной путь, если вам действительно нужно отправлять маринованные данные через JSON, - это использовать 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 голос
/ 09 октября 2010

Может быть ошибка в рассоле.Моя документация по питону говорит (для используемого формата 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
0 голосов
/ 09 октября 2010

Я использую 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'
...