# 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 des caractéristiques distinctes : **`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 présenter 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 un format **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 dans/lecture depuis un fichier. * `json.dumps(obj, ...)` / `json.loads(s, ...)` : conversion en/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 le paramètre `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). * Moins optimisé en termes de taille et de vitesse 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 quasi identique. Il est utile dans les cas suivants : * 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 convient d'éviter `pickle` lorsqu'on charge des données provenant de sources non fiables ou que l'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 le protocole le plus adapté. 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, non 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 principales {#sec-5b2e4c37cce5} * `csv.reader`, `csv.writer` : permet de travailler 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 à retenir {#sec-3db1b7ed8444} 1. **`newline=""`** est indispensable, surtout sous Windows. 2. **Tous les champs sont lus comme des chaînes** ; une conversion manuelle des types est nécessaire. 3. **Les délimiteurs, guillemets et sauts de ligne** peuvent apparaître dans les données ; le module `csv` prend en charge ces cas. ### 3.5 Avantages et inconvénients {#sec-6a8ca4891a8e} **Avantages** * Léger et universel. * Facile à manipuler pour les données tabulaires. **Inconvénients** * Ne convient pas aux structures imbriquées. * Pas de typage explicite, une conversion est donc nécessaire. --- ## 4. Comparaison & guide de choix {#sec-6304ec188cc0} | Critère | JSON | Pickle | CSV | |---------|------|--------|-----| | Compatibilité inter-langages | Excellent | Python uniquement | Excellent | | Lisibilité humaine | Haute | Basse (binaire) | Haute | | Expressivité des types de données | Limitée | Élevée | Limitée | | Sécurité d'utilisation | Relativement sûre | Prudence requise | Relativement sûre | | Structure des données supportées | Arborescente | Objet Python complet | Table (lignes/colonnes) | En résumé : * **É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 importants : * Le CSV nécessite une conversion des types après la lecture. * Pickle est pratique, mais il exige de contrôler la provenance des fichiers. --- ## 6. Conclusion {#sec-f88db3766ed6} La bibliothèque standard Python offre trois options efficaces 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 structure des données et de la finalité du stockage.