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?
>>> 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'}
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”.
JSON has a special value called null which can be set on any type of data including arrays, objects, number and boolean types.
Objects with no value are represented as null. Primitives return their value.
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}
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).
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"
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With