Opslaan en serialiseren met de Python standaardbibliotheek: json, pickle, csv

Wanneer je data in een bestand wilt bewaren of over het netwerk wilt verzenden, heb je serialisatie nodig. Python biedt hiervoor drie vrij verschillende standaardtools: json, pickle en csv.

Data delivery formats

  • json: leesbaar tekstformaat, sterk in inter‑taaluitwisseling
  • pickle: binaire vorm die Python‑objecten exact bewaart, krachtig maar met risico’s
  • csv: eenvoudig tekstformaat voor tabulaire data, zeer universeel

In dit artikel leggen we uit hoe je de juiste module kiest op basis van wat je wilt doen.


1. JSON

1.1 Overzicht

JSON (JavaScript Object Notation) is tekstgebaseerd en taal‑onafhankelijk. Het wordt veel gebruikt voor configuratiebestanden, API‑responses, logs en alles wat je met andere systemen wilt delen. In Python wordt het rechtstreeks beheerd met de json module.

1.2 Kern‑API (alleen de meest gebruikte)

  • json.dump(obj, fp, ...) / json.load(fp, ...) : opslaan/laden naar een bestand
  • json.dumps(obj, ...) / json.loads(s, ...) : omzetten naar/van een string

Belangrijke opties:

  • ensure_ascii=False : internationale tekens (bijv. CJK) niet escapen, maar direct schrijven
  • indent=2 : leesbare, mooi geformatteerde output
  • default=... : een “omweg” voor types die JSON niet kent

1.3 Voorbeeld (basis)

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 JSON‑type‑beperkingen eenvoudig oplossen

JSON ondersteunt standaard alleen dict, list, str, int/float, bool en None. Complexere types, zoals datetime, moeten via default omgezet worden.

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 Voor- en nadelen

Voordelen

  • Taaldonker, ideaal voor uitwisseling
  • Tekst, dus makkelijk debuggen en versiebeheer
  • Geen code‑uitvoering bij laden, dus veiliger dan pickle

Nadelen

  • Beperkte type‑expressie (bijv. datetime, set, Decimal, binaire data)
  • Bij grote datasets kan het minder efficiënt zijn qua grootte en snelheid

2. Pickle

2.1 Overzicht

pickle serialiseert Python‑objecten exact zoals ze zijn. Het resultaat is een binaire byte‑reeks; bij laden krijg je vrijwel dezelfde objecten terug.

Pickle is vooral handig wanneer:

  • Je complexe Python‑objecten wilt bewaren (bijv. eigen klassen, geneste structuren, getrainde modellen)
  • Er geen behoefte is om met andere talen te communiceren

Wees voorzichtig bij het laden van pickle‑bestanden uit onbekende bronnen, want pickle.load() kan willekeurige code uitvoeren.

2.2 Kern‑API (de vier meest gebruikte)

  • pickle.dump(obj, file, protocol=...) : object → bestand (binair)
  • pickle.load(file) : bestand → object
  • pickle.dumps(obj, protocol=...) : object → bytes
  • pickle.loads(data) : bytes → object
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 Protocol – waarom het belangrijk is

Het protocol bepaalt de interne opmaak van de pickle‑data. Zonder expliciete keuze gebruikt Python het meest geschikte standaardprotocol.

  • Oudere Python‑versies: soms moet je een lager protocol gebruiken voor compatibiliteit.
  • Optimalisatie: het nieuwste protocol (pickle.HIGHEST_PROTOCOL) levert vaak kleinere en snellere bestanden.
import pickle

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

2.4 Belangrijkste veiligheidswaarschuwing

pickle.load() voert de herstel‑logica uit die in het bestand is opgeslagen. Laden van een pickle uit een onbeveiligde bron kan leiden tot willekeurige code‑uitvoering.

  • Veilig: open nooit een pickle van een onbekende bron.
  • Vooruit: gebruik bij uitwisseling een tekstgebaseerd formaat zoals json.

2.5 Voor- en nadelen

Voordelen

  • Bewaart vrijwel elk Python‑object
  • Meestal sneller en handiger dan json voor complexe data

Nadelen

  • Beveiligingsrisico bij onbetrouwbare data
  • Alleen Python‑compatibel
  • Versie‑compatibiliteit kan een probleem zijn als klassen veranderen

3. CSV

3.1 Overzicht

CSV (Comma‑Separated Values) is het eenvoudigste formaat voor tabulaire data. Het wordt vaak gebruikt voor spreadsheets, data‑export/import en eenvoudige log‑dump.

3.2 Kern‑API (alleen de meest gebruikte)

  • csv.reader, csv.writer : werken met lijsten
  • csv.DictReader, csv.DictWriter : werken met dictionaries (meestal handiger)

3.3 Voorbeeld (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 Drie belangrijke aandachtspunten

  1. newline="" gebruiken – vooral op Windows voorkomt dubbele nieuwe regels.
  2. Alle waarden zijn strings – bij het lezen moet je zelf de types converteren.
  3. Speciale tekens (komma, aanhalingstekens, nieuwe regels) kunnen de structuur verstoren; het csv‑module is hier veilig voor.

3.5 Voor- en nadelen

Voordelen

  • Zeer lichtgewicht en universeel leesbaar
  • Ideaal voor eenvoudige tabulaire data

Nadelen

  • Niet geschikt voor geneste of complexe structuren
  • Geen type‑informatie, dus extra conversie nodig

4. Vergelijking & keuze‑gids

Kenmerk JSON Pickle CSV
Taal‑compatibiliteit Zeer goed Alleen Python Zeer goed
Leesbaarheid Hoog Laag (binair) Hoog
Type‑expressie Beperkt Zeer hoog Beperkt
Veiligheid Relatief veilig Let op Relatief veilig
Data‑vorm Boom (genest) Exact Python‑object Tabel (rij/kolom)

Korte samenvatting

  • Andere systemen delenjson
  • Python‑objecten volledig bewarenpickle (maar alleen van vertrouwde bronnen)
  • Rij/kolom exportcsv

5. Hetzelfde data in drie formaten opslaan & laden

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)

Belangrijk

  • CSV vereist expliciete type‑conversie.
  • Pickle is handig, maar de bron moet betrouwbaar zijn.

6. Afsluiting

Met alleen de standaardbibliotheek kun je data opslaan en serialiseren op een breed scala aan manieren.

  • Leesbaar en taaldonkerjson
  • Exact Python‑object bewarenpickle
  • Eenvoudige tabulaire exportcsv

Kies op basis van de vorm en het doel van je data – zo wordt het proces snel en overzichtelijk.