2.28. JSON

JSON (JavaScript Object Notation) to zwarty, czytelny dla człowieka format tekstowy do danych strukturalnych. Definiuje sześć typów – string, number, boolean, null, array oraz object – z których każdy mapuje się bezpośrednio na wartość Pythona, więc konwersja między Pythonem a JSON-em jest pojedynczym wywołaniem funkcji w obu kierunkach.

JSON to lingua franca plików konfiguracyjnych i webowych API. Sięgaj po niego, gdy potrzebujesz zapisać na dysku niewielki pakiet ustawień w postaci, którą możesz też odczytać wzrokiem, albo wymienić dane strukturalne z innym programem.

Dwie funkcje pokrywają większość potrzeb:

  • json.dumps()dump string: zamienia wartość Pythona na łańcuch JSON.

  • json.loads()load string: parsuje łańcuch JSON z powrotem na obiekt Pythona.

Para json.dump / json.load (bez s) wykonuje to samo zadanie, ale przyjmuje bezpośrednio obiekt pliku.

2.28.1. Kodowanie (dumps)

import json

config = {
    "name":  "OpenMV",
    "width": 320,
    "tags":  ["red", "round"],
}

text = json.dumps(config)
print(text)

Wynik:

{"name": "OpenMV", "width": 320, "tags": ["red", "round"]}

Mapowanie wygląda tak:

Cokolwiek spoza tego zbioru (niestandardowa klasa, bufor bytes, set) zgłasza TypeError. Najpierw przekonwertuj wartość.

Informacja

Funkcja json.dumps() w CPythonie przyjmuje argument indent dla ładnie sformatowanego wyniku; w MicroPythonie tak nie jest. Jedynym pokrętłem formatowania jest separators, które kontroluje odstępy w wierszu – przekaż (',', ':') dla najbardziej zwartej postaci. Wieloliniowy, wcięty wynik trzeba w razie potrzeby wytworzyć ręcznie.

2.28.2. Dekodowanie (loads)

text = '{"name": "OpenMV", "width": 320}'
config = json.loads(text)
print(config["name"], config["width"])

Wynik:

OpenMV 320

Obiekty JSON stają się dict, tablice stają się list, a reszta mapuje się z powrotem na swoje odpowiedniki w Pythonie. Błędny JSON zgłasza ValueError.

2.28.3. Odczyt i zapis plików

Para oparta na plikach dobrze współpracuje z with:

import json

with open("config.json") as f:
    config = json.load(f)

config["width"] = 640

with open("config.json", "w") as f:
    json.dump(config, f)

Traktuj plik JSON jako kompletny rekord – wczytaj go, zmodyfikuj wartość Pythona, zapisz z powrotem. Próba edycji JSON-a w miejscu wewnątrz pliku zwykle tworzy więcej błędów, niż oszczędza.