18.2. json — Encodage et décodage JSON

Nouveau dans la version 2.6.

JSON (JavaScript Object Notation), spécifié par la RFC 7159 (qui rend la RFC 4627 obsolète) et par le standard ECMA-404, est une interface légère d’échange de données inspirée par la syntaxe des objets littéraux JavaScript (bien que ce ne soit pas un sous-ensemble strict de Javascript [1] ).

json expose une API familière aux utilisateurs des modules de la bibliothèque standard marshal et pickle.

Encodage d’objets Python basiques :

>>> import json
>>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
'["foo", {"bar": ["baz", null, 1.0, 2]}]'
>>> print json.dumps("\"foo\bar")
"\"foo\bar"
>>> print json.dumps(u'\u1234')
"\u1234"
>>> print json.dumps('\\')
"\\"
>>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
{"a": 0, "b": 0, "c": 0}
>>> from StringIO import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'

Encodage compact :

>>> import json
>>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':'))
'[1,2,3,{"4":5,"6":7}]'

Affichage élégant :

>>> import json
>>> print json.dumps({'4': 5, '6': 7}, sort_keys=True,
...                  indent=4, separators=(',', ': '))
{
    "4": 5,
    "6": 7
}

Décodage JSON :

>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
[u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
u'"foo\x08ar'
>>> from StringIO import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
[u'streaming API']

Spécialisation du décodage JSON pour un objet :

>>> import json
>>> def as_complex(dct):
...     if '__complex__' in dct:
...         return complex(dct['real'], dct['imag'])
...     return dct
...
>>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
...     object_hook=as_complex)
(1+2j)
>>> import decimal
>>> json.loads('1.1', parse_float=decimal.Decimal)
Decimal('1.1')

Étendre la classe JSONEncoder :

>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
...     def default(self, obj):
...         if isinstance(obj, complex):
...             return [obj.real, obj.imag]
...         # Let the base class default method raise the TypeError
...         return json.JSONEncoder.default(self, obj)
...
>>> json.dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[', '2.0', ', ', '1.0', ']']

Utiliser json.tool depuis le shell pour valider et afficher élégamment :

$ echo '{"json":"obj"}' | python -m json.tool
{
    "json": "obj"
}
$ echo '{1.2:3.4}' | python -mjson.tool
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

Note

JSON est un sous-ensemble de YAML 1.2. Le JSON produit par les paramètres par défaut de ce module (en particulier, la valeur par défaut de separators) est aussi un sous ensemble de YAML 1.0 et 1.1. Ce module peut alors aussi être utilisé comme sérialiseur YAML.

18.2.1. Utilisation basique

json.dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)

Sérialise obj comme un flux JSON formaté vers fp (un file-like object supportant .write()) utilisant cette table de conversion.

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.

If ensure_ascii is true (the default), all non-ASCII characters in the output are escaped with \uXXXX sequences, and the result is a str instance consisting of ASCII characters only. If ensure_ascii is false, some chunks written to fp may be unicode instances. This usually happens because the input contains unicode strings or the encoding parameter is used. Unless fp.write() explicitly understands unicode (as in codecs.getwriter()) this is likely to cause an error.

Si check_circular est faux (vrai par défaut), la vérification des références circulaires pour les conteneurs sera ignorée, et une référence circulaire résultera en une OverflowError (ou pire).

Si allow_nan est faux (vrai par défaut), une ValueError sera levée lors de la sérialisation de valeurs float extérieures aux bornes (nan, inf, -inf), en respect strict de la spécification JSON. Si allow_nan est vrai, leurs équivalents JavaScript (NaN, Infinity, -Infinity) seront utilisés.

If indent is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0, or negative, will only insert newlines. None (the default) selects the most compact representation.

Note

Since the default item separator is ', ', the output might include trailing whitespace when indent is specified. You can use separators=(',', ': ') to avoid this.

If specified, separators should be an (item_separator, key_separator) tuple. By default, (', ', ': ') are used. To get the most compact JSON representation, you should specify (',', ':') to eliminate whitespace.

encoding is the character encoding for str instances, default is UTF-8.

Si spécifié, default doit être une fonction qui sera appelée pour les objets qui ne peuvent être sérialisés autrement. Elle doit renvoyer une représentation de l’objet encodable en JSON ou lever une TypeError. Si non spécifié, une TypeError sera levée pour les types non-sérialisables.

Si sort_keys est vrai (faux par défaut), les dictionnaires seront retranscrits triés selon leurs clés.

Pour utiliser une sous-classe JSONEncoder personnalisée (p. ex. une qui redéfinit la méthode default() pour sérialiser des types additionnels), spécifiez-la avec le paramètre nommé cls ; autrement, JSONEncoder est utilisée.

Note

Unlike pickle and marshal, JSON is not a framed protocol so trying to serialize more objects with repeated calls to dump() and the same fp will result in an invalid JSON file.

json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding="utf-8", default=None, sort_keys=False, **kw)

Serialize obj to a JSON formatted str using this conversion table. If ensure_ascii is false, the result may contain non-ASCII characters and the return value may be a unicode instance.

The arguments have the same meaning as in dump().

Note

Les clés dans les couples JSON clé/valeur sont toujours de type str. Quand un dictionnaire est converti en JSON, toutes les clés du dictionnaire sont transformées en chaînes de caractères. Ce qui fait que si un dictionnaire est converti en JSON et reconverti en dictionnaire, le résultat peut ne pas être égal à l’original. Ainsi, loads(dumps(x)) != x si x contient des clés qui ne sont pas des chaînes.

json.load(fp[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

Désérialise fp (un file-like object supportant .read(), contenant un document JSON) vers un objet Python en utilisant cette table de conversion.

If the contents of fp are encoded with an ASCII based encoding other than UTF-8 (e.g. latin-1), then an appropriate encoding name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed, and should be wrapped with codecs.getreader(encoding)(fp), or simply decoded to a unicode object and passed to loads().

object_hook est une fonction optionnelle qui sera appelée avec le résultat de chaque objet littéral décodé (chaque dict). La valeur de retour de object_hook sera utilisée à la place du dict. Cette fonctionnalité peut être utilisée pour implémenter des décodeurs personnalisés (p. ex. les class hinting de JSON-RPC).

object_pairs_hook est une fonction optionnelle qui sera appelé pour chaque objet littéral décodé, avec une liste ordonnée de couples. La valeur de retour de object_pairs_hook sera utilisée à la place du dict. Cette fonctionnalité peut être utilisée pour implémenter des décodeurs personnalisés qui s’appuient sur l’ordre dans lequel les couples clé/valeur sont décodés (par exemple, collections.OrderedDict() mémorisera l’ordre d’insertion). object_pairs_hook prend la priorité sur object_hook, si cette dernière est aussi définie.

Modifié dans la version 2.7: Ajout du support de object_pairs_hook.

parse_float, si spécifiée, sera appelée pour chaque nombre réel JSON à décoder sous forme d’une chaîne de caractères. Par défaut, elle est équivalente à float(num_str). Cela peut servir à utiliser un autre type de données ou un autre analyseur pour les nombres réels JSON (p. ex. decimal.Decimal).

parse_int, si spécifiée, sera appelée pour chaque nombre entier JSON à décoder sous forme d’une chaîne de caractères. Par défaut, elle est équivalente à int(num_str). Cela peut servir à utiliser un autre type de données ou un autre analyseur pour les nombres entiers JSON (p. ex. float).

parse_constant, si spécifiée, sera appelée avec l’une des chaînes de caractères suivantes : '-Infinity', 'Infinity' ou 'NaN'. Cela peut servir à lever une exception si des nombres JSON invalides sont rencontrés.

Modifié dans la version 2.7: parse_constant n’est plus appelée pour “null”, “true” ou “false”.

Pour utiliser une sous-classe JSONDecoder personnalisée, spécifiez-la avec l’argument nommé cls ; autrement, JSONDecoder est utilisée. Les arguments nommés additionnels seront passés au constructeur de cette classe.

json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])

Deserialize s (a str or unicode instance containing a JSON document) to a Python object using this conversion table.

If s is a str instance and is encoded with an ASCII based encoding other than UTF-8 (e.g. latin-1), then an appropriate encoding name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed and should be decoded to unicode first.

The other arguments have the same meaning as in load().

18.2.2. Encodeurs et décodeurs

class json.JSONDecoder([encoding[, object_hook[, parse_float[, parse_int[, parse_constant[, strict[, object_pairs_hook]]]]]]])

Décodeur simple JSON.

Applique par défaut les conversions suivantes en décodant :

JSON Python
objet dict
array list
string unicode
number (nombre entier) int, long
number (nombre réel) float
true True
false False
null None

Les valeurs NaN, Infinity et -Infinity sont aussi comprises comme leurs valeurs float correspondantes, bien que ne faisant pas partie de la spécification JSON.

encoding determines the encoding used to interpret any str objects decoded by this instance (UTF-8 by default). It has no effect when decoding unicode objects.

Note that currently only encodings that are a superset of ASCII work, strings of other encodings should be passed in as unicode.

object_hook, si spécifiée, sera appelée avec le résultat de chaque objet JSON décodé et sa valeur de retour sera utilisée à la place du dict donné. Cela peut être utilisé pour apporter des désérialisations personnalisées (p. ex. pour supporter les class hinting de JSON-RPC).

object_pairs_hook, si spécifiée, sera appelée avec le résultat de chaque objet JSON décodé avec une liste ordonnée de couples. Sa valeur de retour sera utilisée à la place du dict. Cette fonctionnalité peut être utilisée pour implémenter des décodeurs personnalisés se basant sur l’ordre dans lequel les couples clé/valeur sont décodés (par exemple, collections.OrderedDict() mémorisera l’ordre d’insertion). object_pairs_hook prend la priorité sur object_hook, si cette dernière est aussi définie.

Modifié dans la version 2.7: Ajout du support de object_pairs_hook.

parse_float, si spécifiée, sera appelée pour chaque nombre réel JSON à décoder sous forme d’une chaîne de caractères. Par défaut, elle est équivalente à float(num_str). Cela peut servir à utiliser un autre type de données ou un autre analyseur pour les nombres réels JSON (p. ex. decimal.Decimal).

parse_int, si spécifiée, sera appelée pour chaque nombre entier JSON à décoder sous forme d’une chaîne de caractères. Par défaut, elle est équivalente à int(num_str). Cela peut servir à utiliser un autre type de données ou un autre analyseur pour les nombres entiers JSON (p. ex. float).

parse_constant, si spécifiée, sera appelée avec l’une des chaînes de caractères suivantes : '-Infinity', 'Infinity' ou 'NaN'. Cela peut servir à lever une exception si des nombres JSON invalides sont rencontrés.

If strict is false (True is the default), then control characters will be allowed inside strings. Control characters in this context are those with character codes in the 0–31 range, including '\t' (tab), '\n', '\r' and '\0'.

If the data being deserialized is not a valid JSON document, a ValueError will be raised.

decode(s)

Return the Python representation of s (a str or unicode instance containing a JSON document).

raw_decode(s)

Decode a JSON document from s (a str or unicode beginning with a JSON document) and return a 2-tuple of the Python representation and the index in s where the document ended.

Elle peut être utilisée pour décoder un document JSON depuis une chaîne qui peut contenir des données supplémentaires à la fin.

class json.JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default]]]]]]]]])

Encodeur JSON extensible pour les structures de données Python.

Supporte par défaut les objets et types suivants :

Python JSON
dict objet
list, tuple array
str, unicode string
int, long, float number
True true
False false
None null

Pour l’étendre afin de reconnaître d’autres types d’objets, il suffit d’en créer une sous-classe et d’implémenter une nouvelle méthode default() qui renverrait si possible un objet sérialisable pour o, ou ferait appel à l’implémentation de la classe mère (qui lèverait une TypeError).

If skipkeys is false (the default), then it is a TypeError to attempt encoding of keys that are not str, int, long, float or None. If skipkeys is true, such items are simply skipped.

If ensure_ascii is true (the default), all non-ASCII characters in the output are escaped with \uXXXX sequences, and the results are str instances consisting of ASCII characters only. If ensure_ascii is false, a result may be a unicode instance. This usually happens if the input contains unicode strings or the encoding parameter is used.

Si check_circular est vrai (par défaut), une vérification aura lieu sur les listes, dictionnaires et objets personnalisés, afin de détecter les références circulaires et éviter les récursions infinies (qui causeraient une OverflowError). Autrement, la vérification n’a pas lieu.

Si allow_nan est vrai (par défaut), alors NaN, Infinity et -Infinity seront encodés comme tels. Ce comportement ne respecte pas la spécification JSON, mais est cohérent avec le majorité des encodeurs/décodeurs JavaScript. Autrement, une ValueError sera levée pour de telles valeurs.

Si sort_keys est vrai (False par défaut), alors les dictionnaires seront triés par clés en sortie ; cela est utile lors de tests de régression pour pouvoir comparer les sérialisations JSON au jour le jour.

If indent is a non-negative integer (it is None by default), then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. None is the most compact representation.

Note

Since the default item separator is ', ', the output might include trailing whitespace when indent is specified. You can use separators=(',', ': ') to avoid this.

If specified, separators should be an (item_separator, key_separator) tuple. By default, (', ', ': ') are used. To get the most compact JSON representation, you should specify (',', ':') to eliminate whitespace.

Si spécifié, default doit être une fonction qui sera appelée pour les objets qui ne peuvent être sérialisés autrement. Elle doit renvoyer une représentation de l’objet encodable en JSON ou lever une TypeError. Si non spécifié, une TypeError sera levée pour les types non-sérialisables.

If encoding is not None, then all input strings will be transformed into unicode using that encoding prior to JSON-encoding. The default is UTF-8.

default(o)

Implémentez cette méthode dans une sous-classe afin qu’elle renvoie un objet sérialisable pour o, ou appelle l’implémentation de base (qui lèvera une TypeError).

Par exemple, pour supporter des itérateurs arbitraires, vous pourriez implémenter default comme cela :

def default(self, o):
   try:
       iterable = iter(o)
   except TypeError:
       pass
   else:
       return list(iterable)
   # Let the base class default method raise the TypeError
   return JSONEncoder.default(self, o)
encode(o)

Renvoie une chaîne JSON représentant la structure de données Python o. Par exemple :

>>> JSONEncoder().encode({"foo": ["bar", "baz"]})
'{"foo": ["bar", "baz"]}'
iterencode(o)

Encode l’objet o donné, et produit chaque chaîne représentant l’objet selon disponibilité. Par exemple :

for chunk in JSONEncoder().iterencode(bigobject):
    mysocket.write(chunk)

18.2.3. Conformité au standard et Interopérabilité

Le format JSON est spécifié par la RFC 7159 et le standard ECMA-404. Cette section détaille la conformité à la RFC au niveau du module. Pour faire simple, les sous-classes de JSONEncoder et JSONDecoder, et les paramètres autres que ceux explicitement mentionnés ne sont pas considérés.

Ce module ne se conforme pas strictement à la RFC, implémentant quelques extensions qui sont valides en JavaScript mais pas en JSON. En particulier :

  • Les nombres infinis et NaN sont acceptés et retranscrits ;
  • Les noms répétés au sein d’un objet sont acceptés, seule la valeur du dernier couple nom/valeur sera utilisée.

Comme la RFC permet aux analyseurs conformes d’accepter des textes en entrée non conformes, le désérialiseur de ce module avec ses paramètres par défaut est techniquement conforme à la RFC.

18.2.3.1. Encodage des caractères

The RFC requires that JSON be represented using either UTF-8, UTF-16, or UTF-32, with UTF-8 being the recommended default for maximum interoperability. Accordingly, this module uses UTF-8 as the default for its encoding parameter.

This module’s deserializer only directly works with ASCII-compatible encodings; UTF-16, UTF-32, and other ASCII-incompatible encodings require the use of workarounds described in the documentation for the deserializer’s encoding parameter.

Comme cela est permis par la RFC, bien que non requis, le sérialiseur du module active ensure_ascii=True par défaut, échappant ainsi la sortie de façon à ce que les chaînes résultants ne contiennent que des caractères ASCII.

La RFC interdit d’ajouter un byte marqueur d’ordre (BOM) au début du texte JSON, et le sérialiseur de ce module n’ajoute pas de tel BOM. La RFC permet, mais ne requiert pas, que les désérialiseurs JSON ignorent ces BOM. Le désérialiseur de ce module lève une ValueError quand un BOM est présent au début du fichier.

La RFC n’interdit pas explicitement les chaînes JSON contenant des séquences de bytes ne correspondant à aucun caractère Unicode valide (p. ex. les surrogates UTF-16 sans correspondance), mais précise que cela peut causer des problèmes d’interopérabilité. Par défaut, ce module accepte et retranscrit (quand présents dans la str originale) les code points de telles séquences.

18.2.3.2. Valeurs numériques infinies et NaN

La RFC ne permet pas la représentation des nombres infinis ou des NaN. Néanmoins, par défaut, ce module accepte et retranscrit Infinity, -Infinity et NaN comme s’ils étaient des valeurs numériques littérales JSON valides.

>>> # Neither of these calls raises an exception, but the results are not valid JSON
>>> json.dumps(float('-inf'))
'-Infinity'
>>> json.dumps(float('nan'))
'NaN'
>>> # Same when deserializing
>>> json.loads('-Infinity')
-inf
>>> json.loads('NaN')
nan

Dans le sérialiseur, le paramètre allow_nan peut être utilisé pour altérer ce comportement. Dans le désérialiseur, le paramètre parse_constant peut être utilisé pour altérer ce comportement.

18.2.3.3. Noms répétés au sein d’un objet

La RFC spécifie que les noms au sein d’un objet JSON doivent être uniques, mais ne décrit pas comment les noms répétés doivent être gérés. Par défaut, ce module ne lève pas d’exception ; à la place, il ignore tous les couples nom/valeur sauf le dernier pour un nom donné :

>>> weird_json = '{"x": 1, "x": 2, "x": 3}'
>>> json.loads(weird_json)
{u'x': 3}

Le paramètre object_pairs_hook peut être utilisé pour altérer ce comportement.

18.2.3.4. Valeurs de plus haut niveau autres qu’objets ou tableaux

L’ancienne version de JSON spécifiée par l’obsolète RFC 4627 demandait à ce que la valeur de plus haut niveau du texte JSON soit un objet ou un tableau JSON (dict ou list Python), et ne soit pas null, un nombre, ou une chaîne de caractères. La RFC 7159 a supprimé cette restriction, jamais implémentée par ce module, que ce soit dans le sérialiseur ou le désérialiseur.

Cependant, pour une interopérabilité maximale, vous pourriez volontairement souhaiter adhérer à cette restriction par vous-même.

18.2.3.5. Limitations de l’implémentation

Certaines implémentations de désérialiseurs JSON peuvent avoir des limites sur :

  • la taille des textes JSON acceptés ;
  • le niveau maximum d’objets et tableaux JSON imbriqués ;
  • l’intervalle et la précision des nombres JSON ;
  • le contenu et la longueur maximale des chaînes JSON.

Ce module n’impose pas de telles limites si ce n’est celles inhérentes aux types de données Python ou à l’interpréteur.

Lors d’une sérialisation JSON, faites attention à ces limitations dans les applications qui utiliseraient votre JSON. En particulier, il est commun pour les nombres JSON d’être désérialisés vers des nombres IEEE 754 à précision double, et donc sujets à l’intervalle et aux limitations sur la précision de cette représentation. Cela est d’autant plus important lors de la sérialisation de valeurs int Python de forte magnitude, ou d’instances de types numériques « exotiques » comme decimal.Decimal.

Notes

[1]Comme noté dans l’errata de la RFC 7159, JSON autorise les caractères littéraux U+2028 (LINE SEPARATOR) et U+2029 (PARAGRAPH SEPARATOR) dans les chaînes de caractères, alors que Javascript (selon le standard ECMAScript édition 5.1) ne le permet pas.