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
}
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
| Funkcja | Co 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
| JSON | Python |
|---|---|
| object | dict |
| array | list |
| string | str |
| number | int / float |
| true / false | True / False |
| null | None |
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)
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