Aller au contenu principal

Convertir JSON en Python

JSON vers Python génère des dataclasses, des TypedDicts ou des modèles Pydantic à partir d’un document d’exemple, dans votre navigateur. Les trois répondent à des questions différentes : une dataclass décrit les données sans aucune dépendance, un TypedDict décrit le dict que json.loads vous a déjà donné, et un modèle Pydantic le valide à la frontière.

100 % local
Structure
Exemple de JSON
0 B1 ligneLig. 1, Col. 1
Erreur de syntaxe · Erreur à la ligne 1, colonne 1

Le document s’arrête trop tôt — il semble tronqué.


^
Code générélecture seule
0 B1 ligne
Si vous en avez, collez plusieurs enregistrements. Cela permet de repérer les champs facultatifs absents de certaines lignes.

Comment fonctionne Convertir JSON en Python ?

Choisissez la forme selon ce que vous comptez faire du résultat. Les trois ne sont pas interchangeables, et choisir la mauvaise est le problème le plus courant avec du Python généré.

dataclass, TypedDict, Pydantic

Une @dataclass vous donne un vrai objet avec accès par attributs, égalité et un repr utile, et aucune dépendance tierce — mais elle ne fait aucune validation, donc un champ annoté int accueillera volontiers la string avec laquelle il a été construit. Un TypedDict annote le simple dictionnaire que json.loads a déjà renvoyé, donc rien ne doit être construit du tout et le vérificateur de types attrape quand même une clé mal orthographiée ; c’est la bonne réponse quand vous faites circuler du JSON parsé tel quel. Un BaseModel Pydantic valide et convertit réellement à la construction, ce que veut un client d’API à sa frontière, au prix d’une dépendance et d’un peu de travail à l’exécution.

L’ordre des champs est un problème de correction, pas de style

Un champ de dataclass avec valeur par défaut ne peut pas en précéder un qui n’en a pas : Python lève une TypeError à l’import, pas à la première utilisation. Comme les champs optionnels reçoivent = None, le générateur émet d’abord tous les champs requis. Un générateur qui préserve ici l’ordre des clés JSON produit un module qui échoue à l’import.

Optional veut dire « peut être None », pas « peut être omis »

Cela piège les gens spécifiquement en Python, parce que Optional[int] se lit comme s’il voulait dire optionnel, alors qu’il veut dire nullable. Dans une dataclass, un champ absent de certains enregistrements est émis Optional[int] = None — l’annotation porte la nullabilité et la valeur par défaut porte l’absence. Dans un TypedDict, les deux sont réellement séparés : une clé absente est NotRequired[int] et une valeur null est Optional[int].

Les clés renommées gardent un alias

La convention Python est le snake_case, et le JSON d’un service JavaScript ne l’est généralement pas. Les clés sont renommées et l’original est conservé — sous forme de commentaire dans une dataclass ou un TypedDict, et sous forme d’un vrai Field(alias=…) dans Pydantic, où cela change le comportement au lieu de simplement le documenter.

Les références anticipées sont mises entre guillemets

Les classes imbriquées sont émises avant les classes qui les utilisent, mais l’annotation reste écrite sous forme de chaîne, ce qui garde le module importable si vous le réorganisez à la main.

Exemple

[
  { "userId": 1, "team": "ops" },
  { "userId": 2 }
]

Généré

from dataclasses import dataclass
from typing import Optional

@dataclass
class User:
    user_id: int  # JSON key: userId
    team: Optional[str] = None

Quelles options et quels cas limites Convertir JSON en Python prend en charge ?

Référence technique et options
ParamètreTypeValeur par défautComportement et cas limites
Formedataclass / TypedDict / pydanticdataclassdataclass pour un objet sans dépendance ; TypedDict pour annoter le dict retourné par json.loads ; pydantic lorsque vous souhaitez que les valeurs soient validées à la frontière.
snake_casebooléenonRenomme les clés selon la convention Python. Dans pydantic, cela devient un véritable alias, donc l’analyse correspond toujours au format fil ; ailleurs, il est enregistré dans un commentaire et vous devez mapper vous-même les clés.
X | NonebooléenoffSyntaxe d’union Python 3.10+ au lieu de Optional[X]. Plus courte, et elle supprime l’import de typing — mais c’est une erreur de syntaxe sur 3.9 et inférieur.
stringtype PythonstrLes formats détectés ne sont pas mappés à datetime ou UUID : json.loads retourne des chaînes, et en annotant une comme datetime, ce serait un mensonge à moins que quelque chose ne la parse.
entier / nombretype Pythonint / floatSéparé selon si un échantillon avait une partie fractionnaire. Les entiers Python sont de précision arbitraire, il n’y a donc pas de distinction int64 à faire ici.
Champ optionnelannotationOptional[T] = NoneDans un TypedDict, une clé absente est NotRequired[T] à la place, ce qui est la distinction que Python fait et que les deux autres formes ne peuvent pas faire.
Ordre des champsrequis d’abordimposéUn champ dataclass sans une valeur par défaut ne peut pas suivre un champ avec une valeur par défaut. Les champs obligatoires sont émis en premier, quel que soit l’ordre des clés JSON.
Objet imbriquéclassréférence entre guillemetsPromu à sa propre classe, défini avant son utilisation, et référencé par une référence avant citée pour que le module survive au réordonnancement.

Questions fréquentes

Lequel choisir : dataclass, TypedDict ou Pydantic ?

Si les données franchissent une frontière de confiance — une réponse HTTP, un webhook, un fichier que quelqu’un a envoyé — utilisez Pydantic, car c’est le seul des trois qui vérifie réellement quelque chose. Si vous annotez des dicts que vous avez déjà parsés et que vous les faites circuler en interne, utilisez TypedDict, qui ne coûte rien à l’exécution. Utilisez une dataclass quand vous voulez un vrai objet et aucune dépendance, en acceptant que les annotations soient de la documentation pour votre vérificateur de types plutôt qu’une garantie.

Pourquoi mes champs sont-ils dans un ordre différent de mon JSON ?

Parce qu’un champ de dataclass avec valeur par défaut ne peut pas venir après un champ sans — Python lève une TypeError quand le module est importé, avant même que votre code ne s’exécute. Les champs optionnels reçoivent = None, donc ils sont tous déplacés après les champs requis. TypedDict et Pydantic n’ont pas cette règle et conservent l’ordre d’origine.

Optional[int] signifie-t-il que la clé peut être absente ?

Non, et c’est la lecture erronée la plus courante du typage Python. Optional[int] signifie que la valeur peut être None. Le fait que la clé puisse être absente est une question séparée, exprimée par une valeur par défaut dans une dataclass ou par NotRequired dans un TypedDict. Le générateur les distingue : une clé absente de certains enregistrements reçoit une valeur par défaut, une valeur null dans certains enregistrements reçoit Optional.

Pourquoi mon horodatage est-il un str plutôt qu’un datetime ?

json.loads renvoie une chaîne, donc l’annoter datetime serait faux tant que quelque chose ne la parse pas. Dans Pydantic, vous pouvez changer l’annotation en datetime et il parse ISO 8601 pour vous, ce qui est une des meilleures raisons de choisir Pydantic. Dans une dataclass ou un TypedDict, changer l’annotation ne change rien à l’exécution et induit chaque lecteur en erreur.

Puis-je utiliser le TypedDict généré sur Python 3.9 ?

Oui — l’import se fait depuis typing_extensions plutôt que typing, c’est pourquoi il est écrit ainsi. NotRequired n’est arrivé dans la bibliothèque standard qu’en 3.11, et typing_extensions le rétroporte vers toutes les versions qui ont TypedDict. Activer l’option X | None, en revanche, exige bien 3.10.

Mon JSON est-il envoyé ?

Non. Parsing, inférence et rendu se produisent tous dans votre navigateur, ce que vous pouvez vérifier dans le panneau Réseau. Rien, dans la génération d’une classe à partir d’un échantillon, n’exige un serveur, et les échantillons que les gens collent sont généralement de vraies charges utiles d’un système auquel ils s’intègrent.