Ga naar hoofdinhoud

11e JSON in een bestand

info

Deze les gebruikt json.dumps en json.loads, uit JSON.

In 11d zette je gegevens om naar JSON-tekst. Om ze te bewaren tot de volgende keer, schrijf je die tekst in een bestand.

Opslaan in een bestand​

Een bestand open je met open(). De "w" betekent write: schrijven. Als het bestand nog niet bestaat, maakt Python het aan; bestaat het wel, dan wordt het overschreven.

import json

scores = [
{"naam": "Sara", "punten": 120},
{"naam": "Alex", "punten": 95},
]

with open("scores.json", "w") as bestand:
json.dump(scores, bestand, indent=2)

print("Opgeslagen.")

Uitvoer:

Opgeslagen.

with zorgt dat het bestand netjes wordt gesloten zodra het ingesprongen blok klaar is. Binnen dat blok heet het open bestand bestand.

Inlezen uit een bestand​

Zonder "w" opent open() een bestand om te lezen. json.load() maakt er weer Python-gegevens van:

import json

scores = [{"naam": "Sara", "punten": 120}, {"naam": "Alex", "punten": 95}]
with open("scores.json", "w") as bestand:
json.dump(scores, bestand)

with open("scores.json") as bestand:
ingelezen = json.load(bestand)

for score in ingelezen:
print(f"{score['naam']}: {score['punten']}")

Uitvoer:

Sara: 120
Alex: 95
Waar staat het bestand?

Op je eigen computer komt scores.json in dezelfde map als je Python-bestand, en daar blijft het staan. Hier in de browser bestaat het bestand tot je de pagina herlaadt: daarna is het weg.


Er gaat iets mis​

Een bestand inlezen dat er nog niet is

open("bestaat_niet.json")

Uitvoer:

FileNotFoundError: [Errno 2] No such file or directory: 'bestaat_niet.json'

Lezen kan alleen als het bestand al bestaat. Sla het eerst op, of controleer de naam: een typefout geeft dezelfde melding.


Opdracht 11e.1: Highscores bewaren​

Sla de lijst highscores op in highscores.json. Lees het bestand daarna in, in een nieuwe variabele, en print de naam van wie de meeste punten heeft.

Verwachte uitvoer:

Winnaar: Noor met 150 punten
import json

highscores = [
    {"naam": "Sara", "punten": 120},
    {"naam": "Noor", "punten": 150},
    {"naam": "Alex", "punten": 95},
]

# Schrijf hier je code
Klik hier voor een tip.

Opslaan met with open("highscores.json", "w") as bestand: en json.dump(...), inlezen met with open("highscores.json") as bestand: en json.load(bestand). Zoek daarna de hoogste met een loop, zoals in les 11c.

Klik hier voor de oplossing.
import json

highscores = [
{"naam": "Sara", "punten": 120},
{"naam": "Noor", "punten": 150},
{"naam": "Alex", "punten": 95},
]

with open("highscores.json", "w") as bestand:
json.dump(highscores, bestand)

with open("highscores.json") as bestand:
ingelezen = json.load(bestand)

beste = ingelezen[0]
for score in ingelezen:
if score["punten"] > beste["punten"]:
beste = score

print(f"Winnaar: {beste['naam']} met {beste['punten']} punten")

Uitvoer:

Winnaar: Noor met 150 punten

Opdracht 11e.2: Een score erbij​

Een echt spel slaat na elk potje de nieuwe score op, zonder de oude kwijt te raken. Schrijf de functie voeg_score_toe(naam, punten): die leest scores.json in, voegt de nieuwe score toe aan de lijst en slaat de lijst weer op. Het bestand begint met een lege lijst.

Verwachte uitvoer:

[{'naam': 'Sara', 'punten': 120}, {'naam': 'Alex', 'punten': 95}]
import json

with open("scores.json", "w") as bestand:
    json.dump([], bestand)


def voeg_score_toe(naam, punten):
    # lees in, voeg toe, sla op
    print(f"Nog te doen: {naam} met {punten} punten")


voeg_score_toe("Sara", 120)
voeg_score_toe("Alex", 95)

with open("scores.json") as bestand:
    print(json.load(bestand))
Klik hier voor een tip.

Drie stappen in de functie: json.load om de lijst in te lezen, .append({"naam": naam, "punten": punten}) om de score toe te voegen, en json.dump in een bestand dat je met "w" opent om alles weer op te slaan.

Klik hier voor de oplossing.
import json

with open("scores.json", "w") as bestand:
json.dump([], bestand)


def voeg_score_toe(naam, punten):
with open("scores.json") as bestand:
scores = json.load(bestand)
scores.append({"naam": naam, "punten": punten})
with open("scores.json", "w") as bestand:
json.dump(scores, bestand)


voeg_score_toe("Sara", 120)
voeg_score_toe("Alex", 95)

with open("scores.json") as bestand:
print(json.load(bestand))

Uitvoer:

[{'naam': 'Sara', 'punten': 120}, {'naam': 'Alex', 'punten': 95}]

Het bestand opent twee keer: eerst om te lezen, dan om te schrijven. Open je het meteen met "w", dan is de oude inhoud al weg voordat je hem hebt ingelezen.