# 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](/media/editor_temp/6/82b2d285-16b0-473a-b88a-cd9a6f6582f2.png) * **`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 {#sec-c0452ee3f8b9} ### 1.1 Vue d’ensemble {#sec-573894aef250} 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) {#sec-7388e1478aff} * `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 {#sec-57d0c0653337} ```python 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 {#sec-a43d0fe8a199} JSON ne supporte que `dict`, `list`, `str`, `int/float`, `bool`, `None`. Pour des objets comme `datetime`, on utilise `default`. ```python 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 {#sec-667d6fad184b} **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 {#sec-7417b1955ccc} ### 2.1 Vue d’ensemble {#sec-1889607ea8cb} `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 {#sec-a0a97fe87a25} * `pickle.dump(obj, file, protocol=...)` * `pickle.load(file)` * `pickle.dumps(obj, protocol=...)` * `pickle.loads(data)` Exemple de sauvegarde/chargement depuis un fichier : ```python 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 {#sec-1f8e5565848c} `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. ```python import pickle with open("data.pkl", "wb") as f: pickle.dump({"x": 1}, f, protocol=pickle.HIGHEST_PROTOCOL) ``` ### 2.4 Risques de sécurité {#sec-007b70a5e9ec} `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 {#sec-bbd5a24bec31} **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 {#sec-99e590b24e50} ### 3.1 Vue d’ensemble {#sec-1265cc44a461} 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 {#sec-5b2e4c37cce5} * `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` {#sec-524921270351} ```python 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 {#sec-3db1b7ed8444} 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 {#sec-6a8ca4891a8e} **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 {#sec-6304ec188cc0} | 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èmes** → `json`. * **Conserver un objet Python tel quel** → `pickle` (avec prudence). * **Exporter/importer des tables** → `csv`. --- ## 5. Stockage et récupération de la même donnée avec les trois formats {#sec-21f8c2a6d6c9} ```python 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 {#sec-f88db3766ed6} 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.