19.2. json
— Encodage et décodage JSON¶
Code source : Lib/json/__init__.py
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('\u1234'))
"\u1234"
>>> print(json.dumps('\\'))
"\\"
>>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
{"a": 0, "b": 0, "c": 0}
>>> from io 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))
{
"4": 5,
"6": 7
}
Décodage JSON :
>>> import json
>>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]')
['foo', {'bar': ['baz', None, 1.0, 2]}]
>>> json.loads('"\\"foo\\bar"')
'"foo\x08ar'
>>> from io import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)
['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 -m json.tool
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Voir Interface en ligne de commande pour une documentation détaillée.
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.
19.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, default=None, sort_keys=False, **kw)¶ Sérialise obj comme un flux JSON formaté vers fp (un file-like object gérant
.write()
) utilisant cette table de conversion.Si skipkeys est vrai (faux par défaut), alors les clefs de dictionnaires qui ne sont pas de types basiques (
str
,int
,float
,bool
,None
) seront ignorées, elles provoquent normalement la levée d’uneTypeError
.Le module
json
produit toujours des objetsstr
, et non des objetsbytes
.fp.write()
doit ainsi supporter un objetstr
en entrée.Si ensure_ascii est vrai (par défaut), il est garanti que les caractères non ASCII soient tous échappés sur la sortie. Si ensure_ascii est faux, ces caractères seront écrits comme tels.
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 valeursfloat
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.Si indent est un nombre entier positif ou une chaîne de caractères, les éléments de tableaux et les membres d’objets JSON seront affichés élégamment avec ce niveau d’indentation. Un niveau d’indentation de 0, négatif, ou
""
n’insérera que des retours à la ligne.None
(la valeur par défaut) choisit la représentation la plus compacte. Utiliser un entier positif comme indentation indente d’autant d’espaces par niveau. Si indent est une chaîne (telle que"\t"
), cette chaîne est utilisée pour indenter à chaque niveau.Modifié dans la version 3.2: Autorise les chaînes en plus des nombres entiers pour indent.
Si spécifié, separators doit être un tuple
(item_separator, key_separator)
. Sa valeur par défaut est(', ', ': ')
si indent estNone
, et(',', ': ')
autrement. Pour obtenir la représentation JSON la plus compacte possible, vous devriez spécifier(',', ':')
pour éliminer les espacements.Modifié dans la version 3.4: Utilise
(',', ': ')
par défaut si indent n’est pasNone
.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 sérialisable en JSON ou lever une
TypeError
. Si non spécifié, uneTypeError
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éthodedefault()
pour sérialiser des types additionnels), spécifiez-la avec le paramètre nommé cls ; autrement,JSONEncoder
est utilisée.
-
json.
dumps
(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)¶ Sérialise obj vers un JSON formaté
str
, en utilisant cette table de conversion. Les arguments ont la même signification que ceux dedump()
.Note
À l’inverse de
pickle
etmarshal
, JSON n’est pas un protocole par trames, donc essayer de sérialiser de multiples objets par des appels répétés àdump()
en utilisant le même fp résultera en un fichier JSON invalide.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, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **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.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 dudict
. 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 3.1: 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 3.1: 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.Si les données à déserialiser ne sont pas un document JSON valide, une
JSONDecodeError
sera levée.
-
json.
loads
(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)¶ Deserialize s (a
str
instance containing a JSON document) to a Python object using this conversion table.Les autres arguments ont la même signification que pour
load()
, à l’exception d”encoding qui est ignoré et obsolète.Si les données à déserialiser ne sont pas un document JSON valide, une
JSONDecodeError
sera levée.
19.2.2. Encodeurs et décodeurs¶
-
class
json.
JSONDecoder
(object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)¶ Décodeur simple JSON.
Applique par défaut les conversions suivantes en décodant :
JSON Python objet dict array list string str number (nombre entier) int number (nombre réel) float true True false False null None Les valeurs
NaN
,Infinity
et-Infinity
sont aussi comprises comme leurs valeursfloat
correspondantes, bien que ne faisant pas partie de la spécification JSON.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éserialisations 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 3.1: 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'
.Si les données à déserialiser ne sont pas un document JSON valide, une
JSONDecodeError
sera levée.-
decode
(s)¶ Renvoie la représentation Python de s (une instance
str
contenant un document JSON).Une
JSONDecodeError
sera levée si le document JSON donné n’est pas valide.
-
raw_decode
(s)¶ Décode en document JSON depuis s (une instance
str
débutant par un document JSON) et renvoie un tuple de 2 éléments contenant la représentation Python de l’objet et l’index dans s où le document se terminait.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=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)¶ 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 string int, float, et Enums dérivées d”int ou de float number True true False false None null Modifié dans la version 3.4: Ajout du support des classes Enum dérivées d”int ou de float.
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 pouro
, ou ferait appel à l’implémentation de la classe mère (qui lèverait uneTypeError
).Si skipkeys est faux (par défaut), une
TypeError
sera levée lors de l’encodage de clés autres que desstr
, desint
, desfloat
ouNone
. Si skipkeys est vrai, ces éléments sont simplement ignorés.Si ensure_ascii est vrai (par défaut), il est garanti que les caractères non ASCII soient tous échappés sur la sortie. Si ensure_ascii est faux, ces caractères seront écrits comme tels.
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, uneValueError
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.Si indent est un nombre entier positif ou une chaîne de caractères, les éléments de tableaux et les membres d’objets JSON seront affichés élégamment avec ce niveau d’indentation. Un niveau d’indentation de 0, négatif, ou
""
n’insérera que des retours à la ligne.None
(la valeur par défaut) choisit la représentation la plus compacte. Utiliser un entier positif comme indentation indente d’autant d’espaces par niveau. Si indent est une chaîne (telle que"\t"
), cette chaîne est utilisée pour indenter à chaque niveau.Modifié dans la version 3.2: Autorise les chaînes en plus des nombres entiers pour indent.
Si spécifié, separators doit être un tuple
(item_separator, key_separator)
. Sa valeur par défaut est(', ', ': ')
si indent estNone
, et(',', ': ')
autrement. Pour obtenir la représentation JSON la plus compacte possible, vous devriez spécifier(',', ':')
pour éliminer les espacements.Modifié dans la version 3.4: Utilise
(',', ': ')
par défaut si indent n’est pasNone
.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 sérialisable en JSON ou lever une
TypeError
. Si non spécifié, uneTypeError
sera levée pour les types non sérialisables.-
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 json.JSONEncoder.default(self, o)
-
encode
(o)¶ Renvoie une chaîne JSON représentant la structure de données Python o. Par exemple :
>>> json.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 json.JSONEncoder().iterencode(bigobject): mysocket.write(chunk)
-
19.2.3. Exceptions¶
-
exception
json.
JSONDecodeError
(msg, doc, pos)¶ Sous-classe de
ValueError
avec les attributs additionnels suivants :-
msg
¶ Le message d’erreur non formaté.
-
doc
¶ Le document JSON actuellement traité.
-
pos
¶ L’index de doc à partir duquel l’analyse a échoué.
-
lineno
¶ La ligne correspondant à pos.
-
colno
¶ La colonne correspondant à pos.
Nouveau dans la version 3.5.
-
19.2.4. 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éserialiseur de ce module avec ses paramètres par défaut est techniquement conforme à la RFC.
19.2.4.1. Encodage des caractères¶
La RFC requiert que le JSON soit représenté en utilisant l’encodage UTF-8, UTF-16 ou UTF-32, avec UTF-8 recommandé par défaut pour une interopérabilité maximale.
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.
Outre le paramètre ensure_ascii, les conversions entre objets Python et chaînes Unicode
de ce module sont strictement définies, et ne rencontrent donc pas directement le problème de l’encodage des caractères.
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éserialiseurs JSON ignorent ces BOM. Le déserialiseur 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.
19.2.4.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éserialiseur, le paramètre parse_constant peut être utilisé pour altérer ce comportement.
19.2.4.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)
{'x': 3}
Le paramètre object_pairs_hook peut être utilisé pour altérer ce comportement.
19.2.4.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éserialiseur.
Cependant, pour une interopérabilité maximale, vous pourriez volontairement souhaiter adhérer à cette restriction par vous-même.
19.2.4.5. Limitations de l’implémentation¶
Certaines implémentations de déserialiseurs 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éserialisé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
.
19.2.5. Interface en ligne de commande¶
Code source : Lib/json/tool.py
Le module json.tool
fournit une simple interface en ligne de commande pour valider et réécrire élégamment des objets JSON.
Si les arguments optionnels infile
et outfile
ne sont pas spécifiés, sys.stdin
et sys.stdout
seront utilisés respectivement :
$ echo '{"json": "obj"}' | python -m json.tool
{
"json": "obj"
}
$ echo '{1.2:3.4}' | python -m json.tool
Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Modifié dans la version 3.5: La sortie conserve maintenant l’ordre des données de l’entrée. Utilisez l’option --sort-keys
pour sortir des dictionnaires triés alphabétiquement par clés.
19.2.5.1. Options de la ligne de commande¶
-
infile
¶
Le fichier JSON à valider ou réécrire élégamment :
$ python -m json.tool mp_films.json [ { "title": "And Now for Something Completely Different", "year": 1971 }, { "title": "Monty Python and the Holy Grail", "year": 1975 } ]
Si infile n’est pas spécifié, lit le document depuis
sys.stdin
.
-
outfile
¶
Écrit la sortie générée par infile vers le fichier outfile donné. Autrement, écrit sur
sys.stdout
.
-
--sort-keys
¶
Trie alphabétiquement les dictionnaires par clés.
Nouveau dans la version 3.5.
-
-h
,
--help
¶
Affiche le message d’aide.
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. |