2010-08-23 2 views
6

Демпинг и загрузка dict с None as key, приводит к типу с «нулем» в качестве ключа.Python + JSON, что случилось с None?

Значения не подвержены влиянию, но все становится еще хуже, если на самом деле существует «нулевой» строковый ключ.

Что я здесь делаю неправильно? Почему я не могу сериализовать/десериализовать dict с помощью клавиш «Нет»?

Пример

>>> json.loads(json.dumps({'123':None, None:'What happened to None?'})) 
{u'123': None, u'null': u'What happened to None?'} 
>>> json.loads(json.dumps({'123':None, None:'What happened to None?', 'null': 'boom'})) 
{u'123': None, u'null': u'boom'} 
+1

Btw-выход второго кода, похоже, был искажен. –

ответ

17

Объекты JSON - это карты строки значениям. Если вы попытаетесь использовать другой тип ключа, они преобразуются в строки.

>>> json.loads(json.dumps({123: None})) 
{'123': None} 
>>> json.loads(json.dumps({None: None})) 
{'null': None} 
10

Согласно specification, None не является допустимым ключом. Это было бы равносильно выражению объекта JSON, который выглядит как

{ ..., null: ..., ... } 

, который не является действительным (т.е. не может быть сгенерирован с помощью диаграммы синтаксиса.)

Возможно, модуль JSON должен был поднять исключения при сериализации вместо того, чтобы молча генерировать строковое представление значения.

EDIT Просто увидел, что поведение модуля documented (несколько неявно):

Если skipkeys является True (по умолчанию: False), то Dict ключи, которые не базового типа (str, unicode, int, long, float, bool, None) будет пропущен вместо повышения TypeError.

поэтому кажется, что это поведение преднамеренно (я все еще сомневаюсь, учитывая текущую спецификацию JSON).

+1

skipKeys не влияет на наблюдаемое поведение. «Нет» - это базовый тип, поэтому skipKeys = True не приведет к «пропуску», так как skipKeys = False не вызывает TypeError. Мне нужна небольшая заметка в документации, например: «Для обратимой кодировки используйте только строки в качестве ключей». – safl

-1

Как показано в @ dan04, None преобразуется в «null».
Все в порядке, значение хранится в dict с «null:« Что случилось с None? »«

Но затем появился еще один ключ с «нулем».
Значит, старое значение с None/'null'-Key («Что случилось с None?») Перезаписывается «бумом».

+0

Почему downvotes, что не так с этим ответом? –

Смежные вопросы