Rozdział 15 · Python i akta

JSON: zapisujemy struktury danych

Słowniki i listy z rozdziału 11 wreszcie mają niezawodny sposób na przetrwanie restartu programu.

Moduł json

json_dump.py
import json

data = {"name": "Anna", "score": 1200}

with open("igrok.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)
$ cat igrok.json
{
  "name": "Anna",
  "score": 1200
}
Rzeczywiście zapisany plik — zwykły tekst, można go otworzyć w dowolnym edytorze.
json_load.py
import json

with open("igrok.json", "r", encoding="utf-8") as f:
    data = json.load(f)

print(type(data))   # <class 'dict'>
print(data["name"])   # Anna

dump/load vs dumps/loads

FunkcjaCo robi
json.dump(data, file)zapisuje JSON bezpośrednio w otwartym obiekcie pliku
json.dumps(data)zwraca JSON jako zwykły łańcuch znaków str
json.load(file)czyta JSON z otwartego obiektu plikowego
json.loads(text)analizuje JSON z gotowego łańcuch znaków str

Dopasowanie JSON Python ↔ typów

JSONPython
objectdict
arraylist
stringstr
numberint / float
true / falseTrue / False
nullNone

Czego JSON nie potrafi zrobić bezpośrednio

JSON nie przechowuje dowolnego obiektu Python sobie
set, instancja własnej klasy, bytes, complex — żaden z nich nie ma bezpośredniej reprezentacji w JSON. json.dump() nie może „magicznie”
Krotka wraca jako lista podczas czytania
Jeśli zapisujesz tuple jako JSON- array, po ponownym uruchomieniu otrzymasz normalny list, nie tuple – JSON nie rozróżnia tych dwóch typów Python, ma tylko jeden rodzaj „tablicy”
Debug Lab 12: Nieprawidłowy JSON w pliku
slomanny_json.py
with open("nastroyki.json", "w", encoding="utf-8") as f:
    f.write('{"theme": "dark",}')   # dodatkowy przecinek przed }

import json
with open("nastroyki.json", "r", encoding="utf-8") as f:
    data = json.load(f)
Traceback (most recent call last):
json.decoder.JSONDecodeError: Illegal trailing comma before end of object: line 1 column 17 (char 16)
Co widać na ekranie

Obecność pliku nie oznacza, że jego zawartość to poprawny JSON: plik mógł zostać uszkodzony, edytowany ręcznie lub zapisany błędnie w innym miejscu programu. json.JSONDecodeError — sygnał dokładnie o tym, a nie o problemie ze ścieżką lub uprawnieniami.

Poprawiony kod
json_bez_zapyatoj.py
with open("nastroyki.json", "w", encoding="utf-8") as f:
    f.write('{"theme": "dark"}')

Mini Projekt: Menedżer ustawień

Ustawienia aplikacji, które będą potrzebne w aplikacji graficznej rozdziału 16 — z zrozumiałymi wartościami domyślnymi, jeśli plik jeszcze nie istnieje:

nastroyki_menedzher.py
import json
from pathlib import Path

DEFAULT_SETTINGS = {"theme": "light", "language": "ru", "window_width": 900}

def load_settings(path: Path) -> dict:
    if not path.exists():
        return dict(DEFAULT_SETTINGS)
    with path.open("r", encoding="utf-8") as f:
        return json.load(f)

def save_settings(path: Path, settings: dict) -> None:
    with path.open("w", encoding="utf-8") as f:
        json.dump(settings, f, ensure_ascii=False, indent=2)

settings_path = Path("nastroyki.json")
settings = load_settings(settings_path)
settings["theme"] = "dark"
save_settings(settings_path, settings)
Przygotowanie gruntu pod rozdział 16
W ten sposób aplikacja graficzna na Tkinter (Rozdział 16) będzie mogła zapamiętywać ustawienia użytkownika między uruchomieniami — ładować je przy starcie i zapisywać po zmianie, bez żadnej linii kodu interfejsu w tej funkcji.
Praktyka: JSON i menedżer ustawień
interaktywny laptop bezpośrednio w przeglądarce – Python 3.14 przez Pyodide, bez instalacji
Otwórz praktykę →