JSON to Python
Python dataclasses genereren vanuit JSON
JSON-invoer
Python-uitvoer
Wat is JSON naar Python Dataclass-conversie?
JSON naar Python dataclass-conversie neemt een raw JSON-object en produceert een set Python-dataclassedefinities met nauwkeurige type-annotaties. De dataclasses-module van Python, geïntroduceerd in PEP 557 (Python 3.7), genereert __init__-, __repr__- en __eq__-methoden vanuit geannoteerde klassevelden. Wanneer je werkt met JSON API's, configuratiebestanden of berichtenwachtrijen, geven dataclasses je data een getypeerde structuur die editors en typecheckers zoals mypy al tijdens de ontwikkeling kunnen verifiëren.
De methode json.loads() van Python geeft gewone dicts en lijsten terug. Die werken, maar ze bevatten geen type-informatie: een verkeerd gespelde sleutel geeft None terug in plaats van een foutmelding, en je editor kan veldnamen niet automatisch aanvullen. Dataclasses lossen dit op door elke JSON-sleutel te koppelen aan een benoemd, getypeerd veld. Geneste JSON-objecten worden afzonderlijke dataclassedefinities, arrays worden List[T]-annotaties en null-waarden worden Optional[T] met een standaardwaarde van None.
Deze definities met de hand schrijven is mechanisch werk. Je leest de JSON, bepaalt het type van elk veld op basis van de waarde, converteert sleutels van camelCase of snake_case naar Python-conventies en behandelt randgevallen zoals nullable velden en arrays met gemengde typen. Een converter doet dit alles in milliseconden. Je plakt JSON, krijgt correcte dataclass-code terug en gaat verder.
Waarom een JSON naar Python-converter gebruiken?
JSON-structuren handmatig vertalen naar Python-klassedefinities betekent typen raden op basis van voorbeelddata, velden herordenen zodat verplichte vóór optionele komen, en alles bijwerken wanneer de API verandert. Een converter neemt die moeite weg.
Gebruiksscenario's voor JSON naar Python
JSON naar Python-typemapping
Elk JSON-waardetype wordt gekoppeld aan een specifieke Python-type-annotatie. De tabel hieronder laat zien hoe de converter elk JSON-type vertaalt, met zowel de typing-modulesyntaxis (Python 3.7+) als de ingebouwde syntaxis beschikbaar vanaf Python 3.10.
| JSON-type | Voorbeeld | Python (typing) | Python 3.10+ |
|---|---|---|---|
| string | "hello" | str | str |
| number (integer) | 42 | int | int |
| number (float) | 3.14 | float | float |
| boolean | true | bool | bool |
| null | null | Optional[str] | str | None |
| object | {"k": "v"} | @dataclass class | nested model |
| array of strings | ["a", "b"] | List[str] | list[str] |
| array of objects | [{"id": 1}] | List[Item] | list[Item] |
| mixed array | [1, "a"] | List[Any] | list[Any] |
Dataclass Decorator-referentie
De @dataclass-decorator accepteert verschillende parameters die het gedrag van de gegenereerde klasse bepalen. Deze referentie behandelt de opties die het meest relevant zijn bij het werken met JSON-afgeleide data.
| Decorator / Veld | Gedrag | Gebruik wanneer |
|---|---|---|
| @dataclass | Generates __init__, __repr__, __eq__ from field annotations | Standard dataclasses |
| @dataclass(frozen=True) | Makes instances immutable (hashable, no attribute reassignment) | Config objects, dict keys |
| @dataclass(slots=True) | Uses __slots__ for lower memory and faster attribute access | Python 3.10+, large datasets |
| @dataclass(kw_only=True) | All fields require keyword arguments in __init__ | Python 3.10+, many fields |
| field(default_factory=list) | Sets a mutable default without sharing state between instances | List/dict/set defaults |
dataclass vs Pydantic vs TypedDict
Python heeft drie gangbare manieren om getypeerde structuren te definiëren vanuit JSON. Elk past bij een ander gebruiksscenario. Dataclasses zijn de standaardbibliotheekoptie zonder externe afhankelijkheden. Pydantic voegt runtime-validatie toe. TypedDict annoteert gewone dicts zonder een nieuwe klasse te maken.
Codevoorbeelden
Deze voorbeelden laten zien hoe je gegenereerde dataclasses in Python gebruikt, hoe je ze programmatisch vanuit JavaScript produceert en hoe je alternatieve benaderingen zoals Pydantic en CLI-tools kunt gebruiken.
from dataclasses import dataclass
from typing import List, Optional
import json
@dataclass
class Address:
street: str
city: str
zip: str
@dataclass
class User:
id: int
name: str
email: str
active: bool
score: float
address: Address
tags: List[str]
metadata: Optional[str] = None
raw = '{"id":1,"name":"Alice","email":"alice@example.com","active":true,"score":98.5,"address":{"street":"123 Main St","city":"Springfield","zip":"12345"},"tags":["admin","user"],"metadata":null}'
data = json.loads(raw)
# Reconstruct nested objects manually
addr = Address(**data["address"])
user = User(**{**data, "address": addr})
print(user.name) # -> Alice
print(user.address) # -> Address(street='123 Main St', city='Springfield', zip='12345')// Minimal JSON-to-Python-dataclass generator in JS
function jsonToPython(obj, name = "Root") {
const classes = [];
function infer(val, fieldName) {
if (val === null) return "Optional[str]";
if (typeof val === "string") return "str";
if (typeof val === "number") return Number.isInteger(val) ? "int" : "float";
if (typeof val === "boolean") return "bool";
if (Array.isArray(val)) {
const first = val.find(v => v !== null);
return first ? `List[${infer(first, fieldName + "Item")}]` : "List[Any]";
}
if (typeof val === "object") {
const clsName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);
build(val, clsName);
return clsName;
}
return "Any";
}
function build(obj, cls) {
const fields = Object.entries(obj).map(([k, v]) => ` ${k}: ${infer(v, k)}`);
classes.push(`@dataclass\nclass ${cls}:\n${fields.join("\n")}`);
}
build(obj, name);
return classes.join("\n\n");
}
const data = { id: 1, name: "Alice", scores: [98, 85] };
console.log(jsonToPython(data, "User"));
// @dataclass
// class User:
// id: int
// name: str
// scores: List[int]from pydantic import BaseModel
from typing import List, Optional
class Address(BaseModel):
street: str
city: str
zip: str
class User(BaseModel):
id: int
name: str
email: str
active: bool
score: float
address: Address
tags: List[str]
metadata: Optional[str] = None
# Pydantic parses and validates JSON in one step
raw = '{"id":1,"name":"Alice","email":"alice@example.com","active":true,"score":98.5,"address":{"street":"123 Main St","city":"Springfield","zip":"12345"},"tags":["admin","user"],"metadata":null}'
user = User.model_validate_json(raw)
print(user.name) # -> Alice
print(user.model_dump_json()) # -> re-serializes to JSON# Install the generator
pip install datamodel-code-generator
# Generate dataclasses from a JSON file
datamodel-codegen --input data.json --output models.py --output-model-type dataclasses.dataclass
# Generate Pydantic models instead
datamodel-codegen --input data.json --output models.py
# From a JSON string via stdin
echo '{"id": 1, "name": "Alice", "tags": ["admin"]}' | \
datamodel-codegen --output-model-type dataclasses.dataclass
# Output:
# @dataclass
# class Model:
# id: int
# name: str
# tags: List[str]