Python Language
Module JSON
Recherche…
Remarques
Pour une documentation complète, y compris les fonctionnalités spécifiques à la version, consultez la documentation officielle .
Les types
Les défauts
le module json
gérera par défaut l'encodage et le décodage des types ci-dessous:
Types de désérialisation:
JSON | Python |
---|---|
objet | dict |
tableau | liste |
chaîne | str |
nombre (int) | int |
nombre (réel) | flotte |
vrai faux | Vrai faux |
nul | Aucun |
Le module json
comprend également NaN
, Infinity
et -Infinity
comme valeurs flottantes correspondantes, ce qui est en dehors de la spécification JSON.
Types de sérialisation:
Python | JSON |
---|---|
dict | objet |
liste, tuple | tableau |
str | chaîne |
int, float, (int / float) -enums dérivés | nombre |
Vrai | vrai |
Faux | faux |
Aucun | nul |
Pour interdire le codage de NaN
, Infinity
et -Infinity
vous devez encoder avec allow_nan=False
. Cela ValueError
alors une valeur ValueError
si vous tentez de coder ces valeurs.
Sérialisation personnalisée
Il existe différents hooks qui vous permettent de gérer des données qui doivent être représentées différemment. L'utilisation de functools.partial
vous permet d'appliquer partiellement les paramètres pertinents à ces fonctions pour plus de commodité.
Sérialisation:
Vous pouvez fournir une fonction qui fonctionne sur les objets avant qu'ils ne soient sérialisés comme suit:
# my_json module
import json
from functools import partial
def serialise_object(obj):
# Do something to produce json-serialisable data
return dict_obj
dump = partial(json.dump, default=serialise_object)
dumps = partial(json.dumps, default=serialise_object)
Désérialisation:
Il existe différents hooks gérés par les fonctions json, tels que object_hook et parse_float. Pour une liste exhaustive de votre version de python, voir ici .
# my_json module
import json
from functools import partial
def deserialise_object(dict_obj):
# Do something custom
return obj
def deserialise_float(str_obj):
# Do something custom
return obj
load = partial(json.load, object_hook=deserialise_object, parse_float=deserialise_float)
loads = partial(json.loads, object_hook=deserialise_object, parse_float=deserialise_float)
Sérialisation (dé) personnalisée supplémentaire:
Le module json
permet également l’extension / substitution de json.JSONEncoder
et json.JSONDecoder
pour gérer des types divers. Les hooks documentés ci-dessus peuvent être ajoutés par défaut en créant une méthode nommée de manière équivalente. Pour les utiliser, il suffit de passer la classe en tant que paramètre cls
à la fonction concernée. L'utilisation de functools.partial
vous permet d'appliquer partiellement le paramètre cls à ces fonctions, par exemple
# my_json module
import json
from functools import partial
class MyEncoder(json.JSONEncoder):
# Do something custom
class MyDecoder(json.JSONDecoder):
# Do something custom
dump = partial(json.dump, cls=MyEncoder)
dumps = partial(json.dumps, cls=MyEncoder)
load = partial(json.load, cls=MyDecoder)
loads = partial(json.loads, cls=MyDecoder)
Création de JSON à partir de Python dict
import json
d = {
'foo': 'bar',
'alice': 1,
'wonderland': [1, 2, 3]
}
json.dumps(d)
L'extrait ci-dessus renvoie les éléments suivants:
'{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
Créer un dict Python depuis JSON
import json
s = '{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
json.loads(s)
L'extrait ci-dessus renvoie les éléments suivants:
{u'alice': 1, u'foo': u'bar', u'wonderland': [1, 2, 3]}
Stocker des données dans un fichier
L'extrait de code suivant code les données stockées dans d
en JSON et les stocke dans un fichier (remplace le filename
par le nom réel du fichier).
import json
d = {
'foo': 'bar',
'alice': 1,
'wonderland': [1, 2, 3]
}
with open(filename, 'w') as f:
json.dump(d, f)
Récupération des données d'un fichier
L'extrait de code suivant ouvre un fichier codé JSON (remplace le filename
de filename
par le nom réel du fichier) et renvoie l'objet stocké dans le fichier.
import json
with open(filename, 'r') as f:
d = json.load(f)
`load` vs` charges`, `dump` vs` dumps`
Le module json
contient des fonctions à la fois pour lire et écrire depuis et vers des chaînes Unicode, ainsi que pour lire et écrire depuis et vers des fichiers. Celles-ci sont différenciées par un s
dans le nom de la fonction. Dans ces exemples, nous utilisons un objet StringIO, mais les mêmes fonctions s'appliqueraient à tout objet de type fichier.
Ici, nous utilisons les fonctions basées sur les chaînes:
import json
data = {u"foo": u"bar", u"baz": []}
json_string = json.dumps(data)
# u'{"foo": "bar", "baz": []}'
json.loads(json_string)
# {u"foo": u"bar", u"baz": []}
Et ici, nous utilisons les fonctions basées sur les fichiers:
import json
from io import StringIO
json_file = StringIO()
data = {u"foo": u"bar", u"baz": []}
json.dump(data, json_file)
json_file.seek(0) # Seek back to the start of the file before reading
json_file_content = json_file.read()
# u'{"foo": "bar", "baz": []}'
json_file.seek(0) # Seek back to the start of the file before reading
json.load(json_file)
# {u"foo": u"bar", u"baz": []}
Comme vous pouvez le constater, la principale différence est que lors du vidage de données json, vous devez transmettre le descripteur de fichier à la fonction, par opposition à la capture de la valeur de retour. Il convient également de noter que vous devez chercher au début du fichier avant de lire ou d’écrire afin d’éviter toute corruption des données. Lorsque vous ouvrez un fichier, le curseur est placé à la position 0
, de sorte que ce qui suit fonctionnerait également:
import json
json_file_path = './data.json'
data = {u"foo": u"bar", u"baz": []}
with open(json_file_path, 'w') as json_file:
json.dump(data, json_file)
with open(json_file_path) as json_file:
json_file_content = json_file.read()
# u'{"foo": "bar", "baz": []}'
with open(json_file_path) as json_file:
json.load(json_file)
# {u"foo": u"bar", u"baz": []}
Avoir les deux manières de gérer les données json vous permet de travailler de manière idiomatique et efficace avec des formats pyspark
sur json, tels que json-par-line de pyspark
:
# loading from a file
data = [json.loads(line) for line in open(file_path).splitlines()]
# dumping to a file
with open(file_path, 'w') as json_file:
for item in data:
json.dump(item, json_file)
json_file.write('\n')
Appeler `json.tool` depuis la ligne de commande pour imprimer joliment la sortie JSON
Étant donné un fichier JSON "foo.json" comme:
{"foo": {"bar": {"baz": 1}}}
on peut appeler le module directement depuis la ligne de commande (en passant le nom du fichier en argument) pour le faire imprimer:
$ python -m json.tool foo.json
{
"foo": {
"bar": {
"baz": 1
}
}
}
Le module prendra également en compte STDOUT, donc (dans Bash), nous pourrions tout aussi bien:
$ cat foo.json | python -m json.tool
Formatage de la sortie JSON
Disons que nous avons les données suivantes:
>>> data = {"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}
Json ne fait rien de spécial ici:
>>> print(json.dumps(data))
{"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}
Définition de l'indentation pour obtenir une sortie plus jolie
Si nous voulons une jolie impression, nous pouvons définir une taille de indent
:
>>> print(json.dumps(data, indent=2))
{
"cats": [
{
"name": "Tubbs",
"color": "white"
},
{
"name": "Pepper",
"color": "black"
}
]
}
Trier les clés par ordre alphabétique pour obtenir une sortie cohérente
Par défaut, l'ordre des clés dans la sortie est indéfini. Nous pouvons les obtenir par ordre alphabétique pour nous assurer que nous obtenons toujours le même résultat:
>>> print(json.dumps(data, sort_keys=True))
{"cats": [{"color": "white", "name": "Tubbs"}, {"color": "black", "name": "Pepper"}]}
Se débarrasser des espaces pour obtenir une sortie compacte
Nous pourrions vouloir supprimer les espaces inutiles, ce qui est fait en définissant des chaînes de séparation différentes des valeurs par défaut ', '
et ': '
:
>>>print(json.dumps(data, separators=(',', ':')))
{"cats":[{"name":"Tubbs","color":"white"},{"name":"Pepper","color":"black"}]}
JSON codant des objets personnalisés
Si nous essayons juste ce qui suit:
import json
from datetime import datetime
data = {'datetime': datetime(2016, 9, 26, 4, 44, 0)}
print(json.dumps(data))
nous obtenons une erreur en disant TypeError: datetime.datetime(2016, 9, 26, 4, 44) is not JSON serializable
.
Pour pouvoir sérialiser correctement l'objet datetime, nous devons écrire un code personnalisé pour le convertir:
class DatetimeJSONEncoder(json.JSONEncoder):
def default(self, obj):
try:
return obj.isoformat()
except AttributeError:
# obj has no isoformat method; let the builtin JSON encoder handle it
return super(DatetimeJSONEncoder, self).default(obj)
puis utilisez cette classe d'encodeur au lieu de json.dumps
:
encoder = DatetimeJSONEncoder()
print(encoder.encode(data))
# prints {"datetime": "2016-09-26T04:44:00"}