Limbajul în care vorbesc API-urile
API-urile schimbă date sub formă de JSON — text precum {"id": 1, "name": "Ana"}. Modulul json din Python traduce în ambele direcții: json.dumps transformă datele Python în text JSON, iar json.loads analizează textul JSON și îl transformă în date Python.
Nu există niciun strat de mapare de configurat: cheile sunt numele câmpurilor, exact cum sunt scrise. Un dataclass îi dă unei înregistrări o formă fixă, iar dataclasses.asdict o transformă într-un dicționar simplu, gata pentru json.dumps — redenumește cheile manual atunci când API-ul are nevoie de o altă scriere.
Din date Python în JSON
json.dumps produce JSON pe o singură linie, pentru mașini; json.dumps(..., indent=2) produce JSON ușor de citit, pentru oameni și pentru jurnale. Nimic nu este eliminat automat — când un câmp gol nu trebuie să apară în JSON, șterge-l din dicționar înainte de conversie.
Pe o linie și formatat
Ana nu are email, iar funcția ajutătoare elimină câmpul gol din dicționarul ei — JSON-ul ei rămâne curat. Înregistrarea completă a lui Ben se afișează indentată.
Ieșire: program Python complet
import json
from dataclasses import dataclass, asdict
@dataclass
class User:
id: int
name: str
email: str = ""
def to_json_dict(user):
data = asdict(user) # cheile sunt numele câmpurilor, exact cum sunt scrise
if data["email"] == "":
del data["email"] # elimină manual câmpul gol
return data
ana = User(id=1, name="Ana")
print(json.dumps(to_json_dict(ana)))
ben = User(id=2, name="Ben", email="[email protected]")
print(json.dumps(to_json_dict(ben), indent=2))
Din JSON în date Python
json.loads analizează JSON-ul și îl transformă în date Python simple — dicționare, liste, șiruri, numere. Cheile necunoscute nu sunt aruncate: tot ce se află în JSON ajunge în dicționar, iar o înregistrare tipizată se construiește doar din câmpurile de care are nevoie. Un JSON greșit ridică json.JSONDecodeError — prinde această excepție; ea este semnalul că textul nu era deloc JSON.
Loads și cheia în plus
JSON-ul conține o cheie extra pe care dataclass-ul User nu o are — json.loads o păstrează în dicționar, iar dataclass-ul alege pur și simplu cele două câmpuri de care are nevoie. Un JSON stricat, în schimb, ridică o eroare reală.
Ieșire: program Python complet
import json
from dataclasses import dataclass
@dataclass
class User:
id: int
name: str
data = '{"id": 7, "name": "Cleo", "extra": "kept"}'
raw = json.loads(data)
print(raw) # cheia necunoscută este păstrată în dicționar
user = User(id=raw["id"], name=raw["name"]) # alege câmpurile de care ai nevoie
print(user)
try:
json.loads('{"id": ')
except json.JSONDecodeError as err:
print("eroare:", err)
Date imbricate
Datele reale ale unui API sunt imbricate: o comandă conține utilizatorul ei și o listă de articole. Dataclass-urile din interiorul altor dataclass-uri și listele se transformă automat în obiecte și tablouri JSON — asdict parcurge întreaga structură.
O comandă cu un utilizator în interior
Dataclass-ul imbricat User devine un obiect JSON imbricat, iar lista de articole devine un tablou JSON — forma datelor Python este forma JSON-ului.
Ieșire: program Python complet
import json
from dataclasses import dataclass, asdict
@dataclass
class User:
id: int
name: str
@dataclass
class Order:
id: int
items: list[str]
user: User
order = Order(id=1042, items=["keyboard", "mouse"], user=User(id=1, name="Ana"))
print(json.dumps(asdict(order), indent=2))