← Retour au Blog

Python et JSON : Guide complet pour manipuler des données JSON

Maîtrisez la manipulation JSON en Python avec le module json. Apprenez à lire, écrire, parser et convertir des données JSON avec des exemples pratiques.

Big JSON Team14 min de lectureprogramming
B

Big JSON Team

Technical Writer

Expert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.

14 min de lecture

# Python et JSON : Guide complet pour manipuler des données JSON

Python offre un support excellent pour JSON via son module intégré json. Ce guide complet vous apprend tout ce qu'il faut savoir pour travailler avec JSON en Python.

Le module json de Python

Le module json est inclus dans la bibliothèque standard Python, aucune installation nécessaire.

\\\python

import json

# Le module est prêt à l'emploi

print(json.__version__) # Affiche la version

\\\

Convertir Python en JSON (Serialization)

json.dumps() - Convertir objet Python en chaîne JSON

\\\python

import json

# Dictionnaire Python

utilisateur = {

"nom": "Jean Dupont",

"age": 30,

"ville": "Paris",

"actif": True,

"solde": None

}

# Convertir en JSON

json_string = json.dumps(utilisateur)

print(json_string)

# {"nom": "Jean Dupont", "age": 30, "ville": "Paris", "actif": true, "solde": null}

# Avec indentation pour lisibilité

json_formate = json.dumps(utilisateur, indent=2)

print(json_formate)

"""

{

"nom": "Jean Dupont",

"age": 30,

"ville": "Paris",

"actif": true,

"solde": null

}

"""

\\\

json.dump() - Écrire JSON dans un fichier

\\\python

import json

donnees = {

"entreprise": "TechCorp",

"employes": [

{"nom": "Alice", "role": "Dev"},

{"nom": "Bob", "role": "Manager"}

]

}

# Écrire dans fichier

with open('donnees.json', 'w', encoding='utf-8') as f:

json.dump(donnees, f, indent=2, ensure_ascii=False)

print("Données sauvegardées dans donnees.json")

\\\

Table de conversion Python → JSON

| Type Python | Type JSON |

|-------------|-----------|

| dict | object |

| list, tuple | array |

| str | string |

| int, float | number |

| True | true |

| False | false |

| None | null |

Exemple complet :

\\\python

import json

donnees_python = {

"chaine": "Bonjour",

"entier": 42,

"flottant": 3.14,

"booleen_vrai": True,

"booleen_faux": False,

"nul": None,

"liste": [1, 2, 3],

"tuple": (4, 5, 6), # Converti en array

"dictionnaire": {"cle": "valeur"}

}

json_result = json.dumps(donnees_python, indent=2)

print(json_result)

"""

{

"chaine": "Bonjour",

"entier": 42,

"flottant": 3.14,

"booleen_vrai": true,

"booleen_faux": false,

"nul": null,

"liste": [1, 2, 3],

"tuple": [4, 5, 6],

"dictionnaire": {"cle": "valeur"}

}

"""

\\\

Convertir JSON en Python (Deserialization)

json.loads() - Parser chaîne JSON

\\\python

import json

# Chaîne JSON

json_string = '''

{

"nom": "Jean Dupont",

"age": 30,

"competences": ["Python", "JavaScript", "SQL"],

"actif": true

}

'''

# Convertir en dictionnaire Python

donnees = json.loads(json_string)

print(type(donnees)) #

print(donnees["nom"]) # Jean Dupont

print(donnees["competences"]) # ['Python', 'JavaScript', 'SQL']

print(donnees["actif"]) # True

\\\

json.load() - Lire JSON depuis fichier

\\\python

import json

# Lire fichier JSON

with open('donnees.json', 'r', encoding='utf-8') as f:

donnees = json.load(f)

print(type(donnees)) #

print(donnees)

\\\

Table de conversion JSON → Python

| Type JSON | Type Python |

|-----------|-------------|

| object | dict |

| array | list |

| string | str |

| number (int) | int |

| number (float) | float |

| true | True |

| false | False |

| null | None |

Options avancées de serialization

1. Indentation et formatage

\\\python

import json

donnees = {"nom": "Jean", "age": 30}

# Sans indentation (minifié)

print(json.dumps(donnees))

# {"nom": "Jean", "age": 30}

# Avec indentation de 2 espaces

print(json.dumps(donnees, indent=2))

# {

# "nom": "Jean",

# "age": 30

# }

# Avec indentation de 4 espaces

print(json.dumps(donnees, indent=4))

# Séparateurs personnalisés (sans espaces)

print(json.dumps(donnees, separators=(',', ':')))

# {"nom":"Jean","age":30}

\\\

2. Tri des clés

\\\python

import json

donnees = {

"z_dernier": 1,

"a_premier": 2,

"m_milieu": 3

}

# Sans tri (ordre original)

print(json.dumps(donnees, indent=2))

# Avec tri alphabétique

print(json.dumps(donnees, indent=2, sort_keys=True))

"""

{

"a_premier": 2,

"m_milieu": 3,

"z_dernier": 1

}

"""

\\\

3. Support Unicode

\\\python

import json

donnees = {

"nom": "François",

"ville": "Montréal",

"message": "Bonjour! 你好 مرحبا"

}

# Par défaut : échappe les caractères non-ASCII

print(json.dumps(donnees))

# {"nom": "Fran\u00e7ois", ...}

# Préserver les caractères Unicode

print(json.dumps(donnees, ensure_ascii=False))

# {"nom": "François", "ville": "Montréal", "message": "Bonjour! 你好 مرحبا"}

\\\

4. Encoder les objets personnalisés

\\\python

import json

from datetime import datetime, date

from decimal import Decimal

# Classe personnalisée

class Utilisateur:

def __init__(self, nom, age):

self.nom = nom

self.age = age

# Encoder personnalisé

class EncodeurPersonnalise(json.JSONEncoder):

def default(self, obj):

if isinstance(obj, datetime):

return obj.isoformat()

if isinstance(obj, date):

return obj.isoformat()

if isinstance(obj, Decimal):

return float(obj)

if isinstance(obj, Utilisateur):

return {

"nom": obj.nom,

"age": obj.age

}

return super().default(obj)

# Utilisation

donnees = {

"utilisateur": Utilisateur("Jean", 30),

"date": datetime.now(),

"prix": Decimal("19.99")

}

json_result = json.dumps(donnees, cls=EncodeurPersonnalise, indent=2)

print(json_result)

\\\

Travailler avec des fichiers JSON

Lire et modifier un fichier JSON

\\\python

import json

# Lire

with open('config.json', 'r', encoding='utf-8') as f:

config = json.load(f)

# Modifier

config['version'] = '2.0'

config['nouveauParametre'] = True

# Sauvegarder

with open('config.json', 'w', encoding='utf-8') as f:

json.dump(config, f, indent=2, ensure_ascii=False)

\\\

Fusionner plusieurs fichiers JSON

\\\python

import json

def fusionner_json_files(fichiers, fichier_sortie):

donnees_fusionnees = {}

for fichier in fichiers:

with open(fichier, 'r', encoding='utf-8') as f:

donnees = json.load(f)

donnees_fusionnees.update(donnees)

with open(fichier_sortie, 'w', encoding='utf-8') as f:

json.dump(donnees_fusionnees, f, indent=2, ensure_ascii=False)

# Utilisation

fichiers = ['config1.json', 'config2.json', 'config3.json']

fusionner_json_files(fichiers, 'config_fusion.json')

\\\

Traiter de gros fichiers JSON (streaming)

\\\python

import json

def traiter_gros_fichier(fichier):

"""Traiter JSON ligne par ligne (JSON Lines format)"""

with open(fichier, 'r', encoding='utf-8') as f:

for ligne in f:

if ligne.strip(): # Ignorer lignes vides

obj = json.loads(ligne)

# Traiter chaque objet

print(obj)

# Pour fichier .jsonl ou .ndjson

traiter_gros_fichier('gros_fichier.jsonl')

\\\

Validation JSON

Vérifier si une chaîne est JSON valide

\\\python

import json

def est_json_valide(chaine):

"""Vérifie si la chaîne est un JSON valide"""

try:

json.loads(chaine)

return True

except json.JSONDecodeError:

return False

# Tests

print(est_json_valide('{"nom": "Jean"}')) # True

print(est_json_valide('{"nom": "Jean",}')) # False (virgule finale)

print(est_json_valide("{'nom': 'Jean'}")) # False (guillemets simples)

\\\

Gérer les erreurs de parsing

\\\python

import json

json_invalide = '''

{

"nom": "Jean",

"age": 30,

}

'''

try:

donnees = json.loads(json_invalide)

except json.JSONDecodeError as e:

print(f"Erreur JSON : {e.msg}")

print(f"Ligne {e.lineno}, colonne {e.colno}")

print(f"Position : {e.pos}")

# Erreur JSON : Expecting property name enclosed in double quotes

# Ligne 4, colonne 1

\\\

Travailler avec des API JSON

Requête GET et parser JSON

\\\python

import json

import urllib.request

def obtenir_utilisateur(user_id):

"""Obtenir utilisateur depuis API"""

url = f'https://api.exemple.com/users/{user_id}'

try:

with urllib.request.urlopen(url) as response:

data = response.read()

return json.loads(data)

except Exception as e:

print(f"Erreur : {e}")

return None

# Utilisation

utilisateur = obtenir_utilisateur(123)

if utilisateur:

print(f"Nom : {utilisateur['nom']}")

\\\

Avec requests (recommandé)

\\\python

import requests

# GET request

response = requests.get('https://api.exemple.com/users/123')

utilisateur = response.json() # Parse automatique

print(utilisateur['nom'])

# POST request avec JSON

nouveau_utilisateur = {

"nom": "Jean Dupont",

"email": "jean@exemple.com"

}

response = requests.post(

'https://api.exemple.com/users',

json=nouveau_utilisateur # Encode automatiquement en JSON

)

if response.status_code == 201:

print("Utilisateur créé :", response.json())

\\\

JSON Schema avec jsonschema

\\\python

# Installation : pip install jsonschema

from jsonschema import validate, ValidationError

import json

# Définir le schéma

schema = {

"type": "object",

"properties": {

"nom": {"type": "string", "minLength": 2},

"age": {"type": "number", "minimum": 0, "maximum": 120},

"email": {"type": "string", "format": "email"}

},

"required": ["nom", "email"]

}

# Données à valider

donnees_valides = {

"nom": "Jean Dupont",

"age": 30,

"email": "jean@exemple.com"

}

donnees_invalides = {

"nom": "J", # Trop court

"age": 150, # Trop élevé

"email": "email-invalide"

}

# Valider

try:

validate(instance=donnees_valides, schema=schema)

print("✓ Données valides")

except ValidationError as e:

print(f"✗ Erreur de validation : {e.message}")

try:

validate(instance=donnees_invalides, schema=schema)

except ValidationError as e:

print(f"✗ Erreur : {e.message}")

# 'J' is too short

\\\

Techniques avancées

Pretty print JSON

\\\python

import json

def pretty_print(data):

"""Afficher JSON formaté avec couleurs (si disponible)"""

print(json.dumps(data, indent=2, ensure_ascii=False, sort_keys=True))

donnees = {

"utilisateur": {

"nom": "Jean",

"competences": ["Python", "JavaScript"]

}

}

pretty_print(donnees)

\\\

Aplatir JSON imbriqué

\\\python

def aplatir_json(nested_json, parent_key='', sep='_'):

"""Aplatit un JSON imbriqué"""

items = []

for k, v in nested_json.items():

new_key = f"{parent_key}{sep}{k}" if parent_key else k

if isinstance(v, dict):

items.extend(aplatir_json(v, new_key, sep=sep).items())

else:

items.append((new_key, v))

return dict(items)

# Test

nested = {

"utilisateur": {

"nom": "Jean",

"adresse": {

"ville": "Paris",

"code": "75001"

}

}

}

flat = aplatir_json(nested)

print(flat)

# {'utilisateur_nom': 'Jean', 'utilisateur_adresse_ville': 'Paris',

# 'utilisateur_adresse_code': '75001'}

\\\

Comparer deux JSON

\\\python

import json

def comparer_json(json1, json2):

"""Compare deux objets JSON"""

return json.dumps(json1, sort_keys=True) == json.dumps(json2, sort_keys=True)

a = {"nom": "Jean", "age": 30}

b = {"age": 30, "nom": "Jean"} # Ordre différent

c = {"nom": "Jean", "age": 31} # Valeur différente

print(comparer_json(a, b)) # True (même contenu)

print(comparer_json(a, c)) # False (contenu différent)

\\\

Optimisation des performances

1. ujson (ultra rapide)

\\\python

# Installation : pip install ujson

import ujson

# 2-3x plus rapide que json standard

donnees = {"nom": "Jean", "age": 30}

# Sérialisation

json_str = ujson.dumps(donnees)

# Désérialisation

obj = ujson.loads(json_str)

\\\

2. orjson (le plus rapide)

\\\python

# Installation : pip install orjson

import orjson

# Jusqu'à 5x plus rapide

donnees = {"nom": "Jean", "age": 30}

# Sérialisation (retourne bytes)

json_bytes = orjson.dumps(donnees)

# Désérialisation

obj = orjson.loads(json_bytes)

\\\

Bonnes pratiques

1. Toujours utiliser encoding UTF-8

\\\python

# ✓ Bon

with open('data.json', 'w', encoding='utf-8') as f:

json.dump(data, f)

# ✗ Mauvais (peut perdre caractères spéciaux)

with open('data.json', 'w') as f:

json.dump(data, f)

\\\

2. Gérer les exceptions

\\\python

import json

def charger_json_securise(fichier):

"""Charger JSON avec gestion d'erreurs"""

try:

with open(fichier, 'r', encoding='utf-8') as f:

return json.load(f)

except FileNotFoundError:

print(f"Fichier {fichier} non trouvé")

return {}

except json.JSONDecodeError as e:

print(f"JSON invalide : {e}")

return {}

except Exception as e:

print(f"Erreur inattendue : {e}")

return {}

\\\

3. Valider les données

\\\python

def sauvegarder_config(config, fichier):

"""Sauvegarder config avec validation"""

# Valider types

assert isinstance(config, dict), "Config doit être un dictionnaire"

# Valider clés requises

cles_requises = ['version', 'nom']

for cle in cles_requises:

assert cle in config, f"Clé requise manquante : {cle}"

# Sauvegarder

with open(fichier, 'w', encoding='utf-8') as f:

json.dump(config, f, indent=2, ensure_ascii=False)

\\\

Conclusion

Python offre un excellent support JSON via :

Module standard json :
  • json.dumps() / json.dump() : Python → JSON
  • json.loads() / json.load() : JSON → Python
  • Options de formatage riches
  • Encodeurs personnalisés

Bibliothèques tierces :
  • ujson / orjson : Performance
  • jsonschema : Validation
  • requests : API HTTP + JSON

Points clés :
  • Toujours utiliser encoding='utf-8'
  • Gérer les exceptions JSONDecodeError
  • Valider les données avec JSON Schema
  • Utiliser ensure_ascii=False pour Unicode
  • Préférer requests pour les API
  • Maîtrisez ces techniques et vous manipulerez JSON comme un pro en Python !

    Share:

    Articles Connexes

    Read in English