Convertir une dataclass Python en dictionnaire

Article publié le 07/04/2025 par Jules SAGOT

Convertir une dataclass vers un dictionnaire avec asdict

from dataclasses import asdict, dataclass

@dataclass
class User:
    name: str
    age: int

thomas = User(
    name="Thomas",
    age=40,
)

print(asdict(thomas))

⬇️

{'name': 'Thomas', 'age': 40}

La librairie dataclass fournit la fonction asdict.

Cette fonction convertit une instance de classe décorée avec @dataclass en un dictionnaire.

💡 Le saviez-vous ?

asdict réalise une copie profonde 1 de la dataclass et des objets qu’elle contient.

Convertir une dataclass en JSON avec asdict et json

Une fois qu’on a notre dictionnaire, il suffit d’utiliser la fonction dumps de la librairie standard json.

from dataclasses import asdict, dataclass
import json

@dataclass
class User:
    name: str
    age: int

thomas = User(
    name="Thomas",
    age=40,
)

print(json.dumps(asdict(thomas)))

⬇️

{
    "name": "Thomas",
    "age": 40
}

💡 Le saviez-vous ?

print(json.dumps(asdict(thomas)), sort_keys=True, indent=2)

json.dumps accepte les paramètres suivants qui s’avèrent souvent utiles :

  • sort_keys => Trie les clefs du JSON retourné
  • indent => Améliore la lisibilité avec retours à la ligne et espacements

Le cas de la dataclass imbriquée

asdict va réaliser la conversion de manière récursive sur les dataclasses enfants.

import json
from dataclasses import asdict, dataclass

@dataclass
class ContactDetails:
    email: str
    consent_marketing: bool = False

@dataclass
class User:
    name: str
    age: int
    contact: ContactDetails

thomas = User(
    name="Thomas",
    age=40,
	contact=ContactDetails(email="thomas@octans-solutions.fr")
)

print(json.dumps(asdict(thomas), indent=4, sort_keys=True))

⬇️

{
    "age": 40,
    "contact": {
        "consent_marketing": false,
        "email": "thomas@octans-solutions.fr"
    },
    "name": "Thomas"
}

💡 Le saviez-vous ?

Le code source de Python est disponible en ligne.

Vous pouvez consulter le code source de asdict afin de comprendre en détail comment fonctionne la librairie dataclasses.

Erreur TypeError: ‘User’ object is not iterable

from dataclasses import dataclass

@dataclass
class User:
    name: str
    age: int

thomas = User(
    name="Thomas",
    age=40,
)

dict(thomas)

⬇️💣

TypeError: 'User' object is not iterable

Il n’est pas possible de convertir directement une dataclasse en dictionnaire avec dict().

En effet, l’utilisation du décorateur @dataclass ne permet pas d’ajouter les méthodes keys et getitem requises pour construction du dictionnaire.

💡 Le saviez vous ?

Voici les arguments que dict() 2 peut recevoir :

  1. Une liste de “keywords arguments” (kwargs)
dict(a=1, toto="hello")
  1. Un itérable d’itérables avec deux éléments
dict([('foo', 100), ('bar', 200)])
  1. Un objet qui définit une méthode keys et getitem
from dataclasses import dataclass

@dataclass
class DictSerializable:
    a: int
    toto: str

    def keys(self):
        return ['a', 'toto']

    def __getitem__(self, key):
        return getattr(self, key)

instance = DictSerializable(a=42, toto="hello")
print(dict(instance))

⚠️C’est juste un exemple ! N’utilisez pas l’exemple 3 en production car il ne couvre pas tous les cas d’usages.

Notes

Footnotes

  1. Indiqué dans la documentation de dataclasses.asdict

  2. Documentation du constructeur de dictionnaire Python