Tuples nommés quand l'utilisez-vous ?

Module "collection" ou "typing" ?

a marqué ce sujet comme résolu.

Bonjour à tous,

Je me posais une question : quand est-ce que vous utilisez les namedtuples en pratique ? Quel est l’intérêt par rapport à un dictionnaire ?

Et enfin, je me demande quand utiliser le paquet namedtuple de « collection » et quand utiliser celui de « typing ».

Merci beaucoup ! ;)

Salut,

Personnellement je les utilise quand des noms permettent de mieux comprendre les valeurs associées.

Les intérêts par rapport aux dictionnaires sont multiples :

  • Les clés recherchées sont toujours présentes
  • Ils sont immutables
  • Les clés sont forcément des chaînes (et s’utilisent comme des attributs)
  • Cela reste des tuples tout à fait normaux et on peut les utiliser comme tels

Par contre l’intérêt par rapport aux dataclasses peut être plus discutable.
La différence étant que ces dernières ne sont pas des tuples et représentent donc des données où il n’y a pas de relation d’ordre entre les éléments. Ça évite par exemple de prendre les données pour ce qu’elles ne sont pas (genre un namedtuple représentant une couleur RGB qui serait passé à une fonction attendant un namedtuple représentant un point dans l’espace).

Pour ce qui est de collections ou typing, personnellement je préfère le second car la déclaration est plus « présentable » et que l’on explicite le type des clés. Mais les deux sont plus ou moins équivalentes.

Salut,

Par contre l’intérêt par rapport aux dataclasses peut être plus discutable.
La différence étant que ces dernières ne sont pas des tuples et représentent donc des données où il n’y a pas de relation d’ordre entre les éléments. Ça évite par exemple de prendre les données pour ce qu’elles ne sont pas (genre un namedtuple représentant une couleur RGB qui serait passé à une fonction attendant un namedtuple représentant un point dans l’espace).

Pas sûr de voir ce que tu veux dire, qu’on utilise des dataclass ou des NamedTuple, on se retrouve avec deux class différentes en sortie. Donc si les fonctions sont annotées correctement, les outils statiques genre mypy vont repérer les erreurs. Si tu n’utilises pas d’outil de ce genre, tu te retrouves dans tous les cas avec le problème que le typage dynamique est incapable de fournir un meilleur niveau de preuve que "si ça plante au runtime, c’est qu’il y a une erreur" sans rien pouvoir dire de ce qui se passe si ça ne plante pas au runtime.

Python n’est plus tout jeune, et il s’est développé un peu organiquement en prenant des éléments un peu à droite et à gauche d’autres langages. Donc effectivement, il n’est pas conçu à partir de briques minimales et orthogonales, et beaucoup de choses se recoupent. Il est souvent instructif de lire les PEP à l’origine de certaines fonctionnalités. Par exemple, la PEP 557 des dataclass permet de comprendre un peu mieux pourquoi elles ont été introduites (on peut noter que l’introduction les présente directement comme étant essentiellement des NamedTuple mutables). En l’occurrence, je dirais que les dataclass sont probablement le meilleur investissement parmi toutes les solutions qui se ressemblent, elles permettent d’écrire de façon relativement explicite et légère des product types sans se cogner un __init__ verbeux et répétitif (et tu peux gérer les invariants dans __post_init__).

+0 -0

Pas sûr de voir ce que tu veux dire, qu’on utilise des dataclass ou des NamedTuple, on se retrouve avec deux class différentes en sortie. Donc si les fonctions sont annotées correctement, les outils statiques genre mypy vont repérer les erreurs. Si tu n’utilises pas d’outil de ce genre, tu te retrouves dans tous les cas avec le problème que le typage dynamique est incapable de fournir un meilleur niveau de preuve que "si ça plante au runtime, c’est qu’il y a une erreur" sans rien pouvoir dire de ce qui se passe si ça ne plante pas au runtime.

adri1

Je parle d’un cas d’utilisation basique sans analyse statique : deux namedtuples de types différents partagent globalement la même interface (l’interface des tuples) et sont donc compatibles entre-eux.

Cela ne lève pas d’erreur à l’exécution si seulement les opérations des tuples sont utilisés sur ces objets.

Retirer cette interface commune (en utilisant une dataclass par exemple) empêche d’utiliser un type comme un autre si les noms de leurs champs diffèrent.

Merci pour vos réponses. J’ai un peu l’impression qu’il y a beaucoup de choses en Python qui servent à faire la même chose. :euh:

RDTL

Pas exactement à faire la même chose mais ce sont des approches un peu différentes à des problèmes similaires.

Je parle d’un cas d’utilisation basique sans analyse statique : deux namedtuples de types différents partagent globalement la même interface (l’interface des tuples) et sont donc compatibles entre-eux.

Cela ne lève pas d’erreur à l’exécution si seulement les opérations des tuples sont utilisés sur ces objets.

Il faut aussi que les dimensions des tuples ainsi que les interfaces des divers éléments utilisés soient compatibles pour que ça passe.

Retirer cette interface commune (en utilisant une dataclass par exemple) empêche d’utiliser un type comme un autre si les noms de leurs champs diffèrent.

Mouais, tu remplaces l’interface commune aux NamedTuple par l’interface commune aux dataclass (qui est celle de n’importe quel objet). Dans un cas comme dans l’autre, tu n’échappes pas à la limitation du duck typing qui ne voit que la surface effectivement utilisée de l’interface des instances manipulées (même pas de leurs classes). Alors, certes, l’interface commune entre deux NamedTuple quelconques est un peu plus large qu’entre deux dataclass quelconques, mais ça me parait extrêmement trompeur de déclarer qu’utiliser des dataclass

évite par exemple de prendre les données pour ce qu’elles ne sont pas

de manière significativement plus robuste qu’utiliser des NamedTuple. J’irai même plus loin, le duck typing étant incapable de gérer la sémantique des données manipulées, il est illusoire de se protéger de ça (prendre des données pour ce qu’elles ne sont pas) sans utiliser des outils statiques.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte