Принудительный Python-модуль json для работы с ASCII - PullRequest
16 голосов
/ 06 марта 2012

Я использую json.dump () и json.load () для сохранения / чтения словаря строк на / с диска. Проблема в том, что у меня не может быть строк в юникоде. Кажется, они в юникоде, независимо от того, как я установил параметры для дампа / загрузки (в том числе sure_ascii и encoding).

Ответы [ 2 ]

23 голосов
/ 06 марта 2012

Если вы просто имеете дело с простыми объектами JSON, вы можете использовать следующее:

def ascii_encode_dict(data):
    ascii_encode = lambda x: x.encode('ascii')
    return dict(map(ascii_encode, pair) for pair in data.items())

json.loads(json_data, object_hook=ascii_encode_dict)

Вот пример того, как это работает:

>>> json_data = '{"foo": "bar", "bar": "baz"}'
>>> json.loads(json_data)                                # old call gives unicode
{u'foo': u'bar', u'bar': u'baz'}
>>> json.loads(json_data, object_hook=ascii_encode_dict) # new call gives str
{'foo': 'bar', 'bar': 'baz'}

Этот ответ работает для более сложной структуры JSON и дает хорошее объяснение параметра object_hook. Там также есть другой ответ, который рекурсивно принимает результат вызова json.loads() и преобразует все строки Unicode в строки байтов.

14 голосов
/ 05 февраля 2015

И если объект json представляет собой смесь типов данных, а не только строк в Юникоде, вы можете использовать это выражение:

def ascii_encode_dict(data):
    ascii_encode = lambda x: x.encode('ascii') if isinstance(x, unicode) else x 
    return dict(map(ascii_encode, pair) for pair in data.items())
...