73 votes

Quelle est la différence entre namedtuple et NamedTuple?

La documentation du module typing indique que les deux extraits de code ci-dessous sont équivalents.

 from typing import NamedTuple

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

et

 from collections import namedtuple

Employee = namedtuple('Employee', ['name', 'id'])
 

S'agit-il exactement de la même chose ou, sinon, quelles sont les différences entre les deux implémentations?

71voto

wim Points 35274

Le type générés par le sous-classement typing.NamedTuple est équivalent à un collections.namedtuple, mais avec __annotations__, _field_types et _field_defaults attributs ajoutés. Le code généré va se comporter de la même, à toutes fins pratiques, puisque rien en Python actuellement actes sur ceux de typage des attributs liés (l'IDE peut les utiliser, tout de même).

En tant que développeur, à l'aide de l' typing module pour votre namedtuples permet une approche plus naturelle déclarative de l'interface:

  • Vous pouvez facilement spécifier des valeurs par défaut pour les champs (edit: en Python 3.7, collections.namedtuple a obtenu un nouveau defaults mot-clé si ce n'est plus un avantage)
  • Vous n'avez pas besoin de répéter le nom de type à deux reprises ("Employee")
  • Vous pouvez personnaliser le type directement (par exemple en ajoutant une docstring ou certaines méthodes)

Comme avant, votre classe est une sous-classe de tuple, et les instances seront des instances de tuple comme d'habitude. Fait intéressant, votre classe ne sera pas une sous-classe de NamedTuple:

>>> class Employee(NamedTuple):
...     name: str
...     id: int
...     
>>> issubclass(Employee, NamedTuple)
False
>>> isinstance(Employee(name='guido', id=1), NamedTuple)
False

Si vous voulez savoir pourquoi, lisez la suite pour plus d'informations sur la mise en œuvre actuelle de détail. typing.NamedTuple est une classe, il utilise des metaclasses et une coutume __new__ de gérer les annotations, et puis il délégués collections.namedtuple, de toute façon, à construire et à retourner le type. Comme vous avez pu le deviner à partir de la lowercase nom de convention, collections.namedtuple n'est pas d'un type ou de classe - c'est une usine de fonction. Il fonctionne en construisant une chaîne de code source Python, et puis en appelant exec sur cette chaîne. Le constructeur généré est arraché d'un espace de noms et inclus dans un 3-l'argument de l'invocation de la métaclasse type de construire et de retour de votre classe. C'est ce qui explique l'étrange héritage de casse vu ci-dessus, NamedTuple utilise une métaclasse à l'utilisation de différents métaclasse pour instancier la classe de l'objet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X