Python + JSON, what happened to None?

Question:

Dumping and loading a dict with None as key, results in a dictionary with 'null' as the key.

Values are un-affected, but things get even worse if a string-key 'null' actually exists.

What am I doing wrong here? Why can’t I serialize/deserialize a dict with None keys?

Example

>>> 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'}
Asked By: safl

||

Answers:

According to the specification, None is not a valid key. It would amount to a JSON object expression, which looks like

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

which is not valid (i.e., cannot be generated using the syntax diagram.)

Arguably, the JSON module should have raised an exception upon serialization instead of silently generating a string representation of the value.

EDIT Just saw, that the behaviour of the module is documented (somewhat implicitly):

If skipkeys is True (default: False), then dict keys that are not of a basic type (str, unicode, int, long, float, bool, None) will be skipped instead of raising a TypeError.

so it seems, as if this behaviour is intentional (I still find it questionable given the current JSON specification).

Answered By: Dirk

JSON objects are maps of strings to values. If you try to use another type of key, they’ll get converted to strings.

>>> json.loads(json.dumps({123: None}))
{'123': None}
>>> json.loads(json.dumps({None: None}))
{'null': None}
Answered By: dan04

As @dan04 shows, None is converted to 'null'.

Everything is fine, the value is stored into the dict with

"null": "What happened to None?"

But then came another Key called 'null'.

So the old value of the None/'null'-Key ("What happened to None?") is overwritten with "boom".

Answered By: Duncan MC Leod
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.