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.