Stockage et sérialisation des données avec la bibliothèque standard Python : json, pickle, csv

Pour enregistrer des données dans un fichier ou les transmettre sur un réseau, il faut sérialiser les objets. Python propose trois outils standards, chacun avec un profil différent : json, pickle, csv.

Formats de transport de données

  • json : format texte lisible par l’homme, excellent pour l’échange inter‑langages.
  • pickle : format binaire qui conserve les objets Python tels quels, puissant mais potentiellement dangereux.
  • csv : format texte minimal pour les données tabulaires, très répandu.

Dans cet article, nous allons organiser les critères de choix entre ces trois modules en fonction de l’usage prévu.


1. JSON

1.1 Vue d’ensemble

JSON (JavaScript Object Notation) est texte et indépendant du langage. Il est largement utilisé pour les fichiers de configuration, les réponses/requêtes d’API, les logs, etc. En Python, on l’utilise via le module json.

1.2 API clés (les plus courantes)

  • json.dump(obj, fp, ...) / json.load(fp, ...) : sauvegarde/lecture depuis un fichier.
  • json.dumps(obj, ...) / json.loads(s, ...) : conversion vers/depuis une chaîne.

Options utiles à retenir :

  • ensure_ascii=False : ne pas échapper les caractères non‑ASCII.
  • indent=2 : formatage lisible.
  • default=... : fonction de conversion pour les types inconnus.

1.3 Exemple de base

import json

data = {
    "name": "Alice",
    "age": 30,
    "skills": ["Python", "Data Science"]
}

with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open("data.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)

print(loaded)

1.4 Gérer les limitations de type

JSON ne supporte que dict, list, str, int/float, bool, None. Pour des objets comme datetime, on utilise default.

import json
from datetime import datetime, timezone

payload = {"created_at": datetime.now(timezone.utc)}

def to_jsonable(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    raise TypeError(f"Not JSON serializable: {type(obj)!r}")

s = json.dumps(payload, default=to_jsonable, ensure_ascii=False)
print(s)

1.5 Avantages et inconvénients

Avantages

  • Interopérabilité inter‑langages.
  • Texte, donc débogage et versionnage faciles.
  • Pas d’exécution de code lors du chargement.

Inconvénients

  • Expressivité limitée (datetime, set, Decimal, données binaires).
  • Taille et vitesse moins optimales pour de gros volumes.

2. Pickle

2.1 Vue d’ensemble

pickle sérialise les objets Python exactement tels quels, produisant un flux binaire. Le chargement restitue un objet presque identique.

Il est utile lorsque :

  • Vous devez conserver des objets complexes (classes, modèles entraînés, caches).
  • Vous n’avez pas besoin d’échanger avec d’autres langages.

Il faut éviter pickle lorsqu’on charge des données provenant de sources non fiables ou lorsqu’on souhaite partager les données.


2.2 API principales

  • pickle.dump(obj, file, protocol=...)
  • pickle.load(file)
  • pickle.dumps(obj, protocol=...)
  • pickle.loads(data)

Exemple de sauvegarde/chargement depuis un fichier :

import pickle

data = {"a": [1, 2, 3], "b": ("x", "y")}

with open("data.pkl", "wb") as f:
    pickle.dump(data, f)

with open("data.pkl", "rb") as f:
    loaded = pickle.load(f)

print(loaded)

2.3 Le protocole

protocol détermine la version du format pickle. Par défaut, Python choisit la valeur la plus adaptée. On peut spécifier pickle.HIGHEST_PROTOCOL pour optimiser la taille et la vitesse.

import pickle

with open("data.pkl", "wb") as f:
    pickle.dump({"x": 1}, f, protocol=pickle.HIGHEST_PROTOCOL)

2.4 Risques de sécurité

pickle.load() exécute le code contenu dans le pickle. Charger un pickle provenant d’une source inconnue peut entraîner une exécution de code malveillant. Il est donc recommandé de ne jamais charger de pickle non fiable.

2.5 Avantages et inconvénients

Avantages

  • Conserve pratiquement tout type d’objet Python.
  • Généralement plus rapide que JSON pour des objets complexes.

Inconvénients

  • Risque de sécurité.
  • Format propre à Python, pas interopérable.
  • Les changements de définition de classe peuvent casser les pickles existants.

3. CSV

3.1 Vue d’ensemble

CSV (Comma‑Separated Values) est le format le plus simple pour les données tabulaires. Il est couramment utilisé pour l’import/export de feuilles de calcul, les logs simples, etc.

3.2 API clés

  • csv.reader, csv.writer : travail avec des listes.
  • csv.DictReader, csv.DictWriter : travail avec des dictionnaires (souvent plus pratique).

3.3 Exemple avec DictWriter/DictReader

import csv

data = [
    {"name": "Alice", "age": 30, "city": "Seoul"},
    {"name": "Bob",   "age": 25, "city": "Busan"},
]

with open("people.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["name", "age", "city"])
    writer.writeheader()
    writer.writerows(data)

with open("people.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    loaded = list(reader)

print(loaded)

3.4 Points d’attention

  1. newline="" est indispensable, surtout sous Windows.
  2. Tous les champs sont lus comme des chaînes ; il faut convertir les types manuellement.
  3. Les délimiteurs, guillemets et sauts de ligne peuvent apparaître dans les données ; le module csv gère ces cas.

3.5 Avantages et inconvénients

Avantages

  • Léger et universel.
  • Facile à manipuler pour les données tabulaires.

Inconvénients

  • Pas adapté aux structures imbriquées.
  • Pas de type explicite, conversion nécessaire.

4. Comparaison & guide de choix

Critère JSON Pickle CSV
Compatibilité langage Excellent Python uniquement Excellent
Lisibilité Haute Basse (binaire) Haute
Expressivité des types Limitée Élevée Limitée
Sécurité Relativement sûre Attention requise Relativement sûre
Structure des données Arborescente Objet Python complet Table (lignes/colonnes)

En une phrase :

  • Échange inter‑systèmesjson.
  • Conserver un objet Python tel quelpickle (avec prudence).
  • Exporter/importer des tablescsv.

5. Stockage et récupération de la même donnée avec les trois formats

import json, pickle, csv

data = [
    {"id": 1, "name": "Alice", "score": 95.5},
    {"id": 2, "name": "Bob",   "score": 88.0},
]

# 1) JSON
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open("data.json", "r", encoding="utf-8") as f:
    json_loaded = json.load(f)

# 2) Pickle
with open("data.pkl", "wb") as f:
    pickle.dump(data, f)

with open("data.pkl", "rb") as f:
    pickle_loaded = pickle.load(f)

# 3) CSV
with open("data.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["id", "name", "score"])
    writer.writeheader()
    writer.writerows(data)

with open("data.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    csv_loaded = [
        {"id": int(row["id"]), "name": row["name"], "score": float(row["score"])}
        for row in reader
    ]

print(json_loaded)
print(pickle_loaded)
print(csv_loaded)

Points clés :

  • Le CSV nécessite une conversion de type après la lecture.
  • Pickle est pratique mais exige de contrôler la provenance des fichiers.

6. Conclusion

La bibliothèque standard Python offre trois options puissantes pour le stockage et la sérialisation des données.

  • json : lisible, interopérable.
  • pickle : conserve les objets Python, mais à utiliser avec précaution.
  • csv : simple pour les données tabulaires.

Choisissez le format en fonction de la forme des données et de l’objectif de stockage.