web-dev-qa-db-fra.com

Quelles sont les principales différences de NamedTuple et TypedDict dans Python / mypy

Il me semble que NamedTuple et TypedDict sont assez similaires et les développeurs Python eux-mêmes l'ont reconnu.

Concernant le PEP, je préfère ajouter une section commune sur NamedTuple et TypedDict, ils sont assez similaires et ce dernier se comporte déjà structurellement. Qu'est-ce que tu penses? source

Mais Guido ne semble pas si sûr de cela.

Je ne suis pas sûr que NamedTuple et TypedDict soient vraiment similaires (sauf qu'ils sont tous deux des tentatives de gestion de modèles obsolètes dans un monde statiquement typé).

source

C'est donc ma tentative paresseuse d'amener quelqu'un d'autre à trouver une comparaison précise où la documentation officielle semble faire défaut.

11
Christoph

Python et sa communauté se débattent avec le problème "struct": comment regrouper au mieux les valeurs liées en objets de données composites qui permettent un accès logique/facile aux composants (généralement par nom). Il existe de nombreuses approches concurrentes:

  • collections.namedtuple les instances
  • dictionnaires (avec un jeu de clés fixe/connu)
  • dictionnaires accessibles aux attributs (comme stuf )
  • la bibliothèque attrs
  • PEP 557 classes de données
  • objets sur mesure simples et faits à la main pour chaque type de structure
  • des séquences comme Tuple et list avec des significations implicites pour chaque position/emplacement (archaïque mais extrêmement courant)
  • etc.

Voilà pour "Il devrait y avoir une - et de préférence une seule - façon évidente de le faire."

La bibliothèque typing et Mypy, comme la communauté Python dans son ensemble, se débattent simultanément pour définir plus efficacement les types/schémas, y compris pour les objets composites. La discussion que vous avez liée faire partie de cette lutte et essayer de trouver une voie à suivre.

NamedTuple est une superclasse de typage pour les objets structurés résultant du collections.namedtuple usine; TypedDict une tentative Mypy de définir les clés et les types de valeurs correspondants qui se produisent lors de l'utilisation de dictionnaires à schéma fixe. Ils sont similaires si vous pensez simplement à "J'ai un ensemble fixe de clés qui devrait correspondre à un ensemble fixe de valeurs saisies". Mais les implémentations et les contraintes qui en résultent sont très différentes. Un sac et une boîte sont-ils similaires? Peut être. Peut être pas. Cela dépend de votre point de vue et de la façon dont vous souhaitez les utiliser. Versez du vin et laissez la discussion commencer!

NamedTuple, soit dit en passant, est maintenant une partie formelle de Python.

from typing import NamedTuple

class Employee(NamedTuple):
    name: str
    id: int

TypedDict n'est pas une partie de Python propre, mais une fonctionnalité expérimentale de Mypy pour agiter la saisie sur le utilisation hétérogène et structurée des dictionnaires.

from mypy_extensions import TypedDict

Movie = TypedDict('Movie', {'name': str, 'year': int})

Malgré leurs différences, NamedTuple et TypedDict verrouillent les clés spécifiques à utiliser et les types de valeurs correspondant à chaque clé. Par conséquent, ils visent essentiellement le même objectif: être des mécanismes de typage utiles pour les types composites/struct.

Standard de Python typing.Dict se concentre sur des mappages parallèles beaucoup plus homogènes, définissant des types clé/valeur, et non des clés en soi . Par conséquent, il n'est pas très utile pour définir des objets composites qui se trouvent être stockés dans des dictionnaires.

ConnectionOptions = Dict[str, str] 
1
Jonathan Eunice

NamedTuple est un type spécifique. Comme son nom l'indique, c'est un tuple qui est étendu pour avoir des entrées nommées.

TypedDict n'est pas un véritable objet, vous ne pouvez pas (ou du moins ne devriez pas) l'utiliser, il est plutôt utilisé pour ajouter des informations de type (pour le vérificateur de type mypy) pour annoter des types dans des scénarios lorsque le dictionnaire a divers des clés de types différents, c'est-à-dire essentiellement tous les endroits où il faut utiliser NamedTuple. Il est très utile d'annoter le code existant que vous ne souhaitez pas refactoriser.

0
Derek