Le guide complet sur les namedtuple en Python
En Python, un namedtuple
est une extension du tuple classique qui permet d’accéder à ses éléments par des noms explicites, tout en conservant la légèreté et l’immuabilité du tuple.
Tout ceci fait du namedtuple un type idéal pour structurer des données sans qu'on ait besoin de créer une classe complète !
Définition du namedtuple
Un namedtuple
est un type personnalisé de tuple dont les champs peuvent être accédés via un nom plutôt qu’un index.
Cela rend le code plus clair, notamment dans les fonctions qui retournent plusieurs valeurs ou manipulent des données structurées.
Il faut y penser comme un tuple mais avec des étiquettes ! 😉
Créer un namedtuple
Pour créer un namedtuple
, on utilise collections.namedtuple
:
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 5)
print(p.x) # 3
print(p.y) # 5
Dans cet exemple, on crée un nouveau type de données qu'on appelle Point
.
Ce type agit comme un tuple
mais avec des valeurs nommées. Ceci veut dire qu'au lieu d'accéder aux données par leur position (comme p[0]
), on peut utiliser des noms clairs et explicites (comme p.x
ou p.y
dans notre exemple).
Ensuite, lorsqu'on écrit p = Point(3, 5)
, on instancie ce namedtuple
avec les valeurs 3 et 5, qui iront directement sur les paramètres x
et y
qu'on a défini dans la création de ce dernier.
Ainsi lorsqu'on utilise print(p.x)
Python va aller chercher le paramètre nommé x
(ce qui nous donne 3).
Accéder aux valeurs (index et clés nommées)
Avec un namedtuple
, il est possible d'accéder aux valeurs par deux moyens :
- Par leur clé nommée (ce que nous venons de voir) ;
- Mais aussi par leur index ! 😋
Accéder par les clés nommées
Comme nous l'avons vu dans notre exemple précédent, il est possible d'accéder aux éléments d'un namedtuple
par les clés nommées :
print(utilisateurA.prenom)
Accéder par l'index
Un namedtuple
peut également être utilisé comme un tuple
classique :
print(utilisateurA[0])
Bien que possible, l'intérêt d'un
namedtuple
reste quand même d'en profiter avec des clés nommées ! Elles apportent plus de lisibilité.
namedtuple vs tuple : quelles différences ?
Pourquoi préférer un namedtuple
à une classe simple ou à un tuple
brut ?
Bien que le namedtuple
repose sur sa structure, il apporte une couche de lisibilité et de structure qui en fait un outil bien plus adapté dans de nombreux cas concrets.
Un tuple
standard est une séquence immuable, mais ses éléments doivent être accédés par index. Cela peut rapidement nuire à la clarté du code, surtout si le tuple
contient plusieurs champs.
Le namedtuple
, lui, permet de nommer les champs, ce qui rend leur usage explicite et auto-documenté.
Prenons un exemple parlant :
# Tuple classique
point = (3, 5)
print(point[0]) # x
print(point[1]) # y
# namedtuple
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 5)
print(p.x) # 3
print(p.y) # 5
Dans le premier cas, nous devons nous souvenir que l’index 0
correspond à x
et que 1
correspond à y
. Dans le second cas, les noms parlent d’eux-mêmes.
Autre avantage : un namedtuple
fournit des méthodes pratiques supplémentaires comme _fields
, _asdict()
ou _replace()
(nous allons les voir juste après), qui n’existent pas sur les tuples classiques.
Pour aller plus loin, faisons un tableau récapitulatif :
Critère | tuple | namedtuple |
Accès aux éléments | Par index (t[0] ) | Par nom et index (p.x , p[0] ) |
Lisibilité du code | Faible (pas de nom explicite) | Forte (noms de champs clairs) |
Mutabilité | Immuable | Immuable |
Définition des champs | Aucun nom (que des index) | Champs nommés |
Méthodes utilitaires | ❌ Aucune | _fields , _asdict() , _replace() |
Poids mémoire / performance | Très léger | Légèrement plus lourd |
Utilisation comme clé | ✅ Oui | ✅ Oui |
Représentation | (3, 5) | Point(x=3, y=5) |
Importation requise ? | ❌ Non | ✅ Oui (collections ) |
En résumé : utilisez un
tuple
pour des données très simples et temporaires, mais préférez unnamedtuple
dès que vous voulez plus de lisibilité, de structure, ou un équivalent de classe légère.
Les méthodes spéciales des namedtuple
Contrairement aux tuples
classiques, les namedtuple
fournissent plusieurs méthodes intégrées très pratiques. Elles facilitent la conversion, la mise à jour ou l’inspection des données, tout en conservant l’immuabilité.
Voir les noms des champs avec _fields
Cette propriété renvoie un tuple contenant les noms des champs définis lors de la création du namedtuple
.
Point = namedtuple("Point", ["x", "y"])
print(Point._fields) # ('x', 'y')
Convertir en dictionnaire avec _asdict()
Cette méthode transforme une instance de namedtuple
en dictionnaire ordonné (OrderedDict
). Pratique pour l'affichage, la sérialisation ou le debug.
p = Point(3, 5)
print(p._asdict()) # {'x': 3, 'y': 5}
Créer une nouvelle instance avec une valeur modifiée grâce à _replace()
Comme un namedtuple
est immuable, on ne peut pas modifier ses champs. Mais avec _replace()
, on peut créer une copie avec une ou plusieurs valeurs modifiées.
p2 = p._replace(x=10)
print(p2) # Point(x=10, y=5)
namedtuple vs dataclass : quelles différences ?
Depuis Python 3.7, les dataclass
sont devenues une alternative moderne et souple aux namedtuple
, tout en apportant plus de puissance et de flexibilité. Mais elles ne remplacent pas totalement les namedtuple
: chaque outil a son utilité.
Faisons un résumé comparatif :
Critère | namedtuple | dataclass |
Disponibilité | Depuis Python 2.6 | Depuis Python 3.7 |
Syntaxe | Moins intuitive (fonction dédiée) | Plus naturelle (décorateur @dataclass) |
Immuabilité par défaut | ✅ Oui | ❌ Non (mais possible avec frozen=true ) |
Accès aux champs | Par nom (p.x ) | Par nom (p.x ) |
Type hinting | ❌ Non obligatoire | ✅ Fortement intégré |
Héritage | ❌ Limité | ✅ Supporté |
Méthodes auto-générées | _asdict() , _replace() | __init__() , __repr__() , __eq__() |
Poids mémoire | Très léger | Légèrement plus lourd |
Usage conseillé | Données immuables simples | Structures de données évolutives et typées |
Par exemple ceci est une dataclass
équivalente au namedtuple
que nous avons vu tout à l'heure :
from dataclasses import dataclass
@dataclass(frozen=True)
class Point:
x: int
y: int
p = Point(3, 5)
print(p.x) # 3
Questions fréquentes sur les namedtuple
Voici les questions les plus fréquentes quand on parle de namedtuple
! 😋
Quelle est la différence entre
tuple
etnamedtuple
?
Un tuple
est indexé par position. Un namedtuple
ajoute des noms explicites aux champs, ce qui rend le code plus clair.
Peut-on modifier un
namedtuple
?
Non, les namedtuple
sont immutables. Utilisez _replace()
pour créer une nouvelle version avec une valeur modifiée.
Dois-je utiliser
namedtuple
oudataclass
?
Utilisez namedtuple
pour des structures simples et immuables, et dataclass
si vous avez besoin de plus de flexibilité, comme l’héritage, des valeurs par défaut, ou des méthodes personnalisées.
Quelle est la meilleure formation Python pour apprendre en partant de zéro ?
Surement cette formation Python à jour avec les dernières nouveautés !