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, uitermate geschikt voor taaloverstijgende uitwisseling
  • 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 de specifieke taak die je wilt uitvoeren.


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 direct verwerkt 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 methode voor types die JSON niet standaard ondersteunt

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

  • Taalonafhankelijk, ideaal voor uitwisseling
  • Tekst, dus gemakkelijk te debuggen en geschikt voor 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 herstellogica 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 logbestanden.

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; de 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
Taalcompatibiliteit Zeer goed Alleen Python Zeer goed
Leesbaarheid Hoog Laag (binair) Hoog
Type-expressie Beperkt Zeer hoog Beperkt
Veiligheid Relatief veilig Let op Relatief veilig
Datavorm Boom (genest) Exact Python‑object Tabel (rij/kolom)

Korte samenvatting

  • Voor het delen met andere systemenjson
  • Python‑objecten volledig bewarenpickle (maar alleen van vertrouwde bronnen)
  • Voor export van gegevens in tabelvormcsv

5. Dezelfde 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 taalonafhankelijkjson
  • 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.