Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python + JSON, what happened to None?

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'}
like image 904
safl Avatar asked Aug 23 '10 14:08

safl


People also ask

Is None valid JSON?

One of the changes in RFC 7159 is that a JSON text is not defined as being an object or an array anymore but rather as being a serialized value. This means that with RFC 7159, “null” (as well as “true” and “false”) becomes a valid JSON text. So the JSON text serialized value of a null object is indeed “null”.

Does JSON use null or None?

JSON has a special value called null which can be set on any type of data including arrays, objects, number and boolean types.

How does JSON represent null?

Objects with no value are represented as null. Primitives return their value.


3 Answers

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}
like image 61
dan04 Avatar answered Oct 14 '22 01:10

dan04


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

like image 18
Dirk Avatar answered Oct 14 '22 02:10

Dirk


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

like image 4
Duncan MC Leod Avatar answered Oct 14 '22 03:10

Duncan MC Leod