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


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow