Tapez des indices dans namedtuple

127

Considérez le morceau de code suivant:

from collections import namedtuple
point = namedtuple("Point", ("x:int", "y:int"))

Le code ci-dessus n'est qu'un moyen de démontrer ce que j'essaie d'accomplir. Je voudrais faire namedtupleavec des indices de type.

Savez-vous comment obtenir un résultat comme prévu?

Pavel Hanpari
la source
2
De plus, à partir de py3.7, vous avez l'option dataclass
JohnE

Réponses:

151

La syntaxe préférée pour un tuple nommé typé depuis 3.6 est

from typing import NamedTuple

class Point(NamedTuple):
    x: int
    y: int = 1  # Set default value

Point(3)  # -> Point(x=3, y=1)

Edit À partir de Python 3.7, envisagez d'utiliser dataclasses(votre IDE peut ne pas encore les prendre en charge pour la vérification de type statique):

from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int = 1  # Set default value

Point(3)  # -> Point(x=3, y=1)
Wolfgang Kuehn
la source
12
@JohnE; L'OP a spécifiquement demandé des tuples nommés. Oui, de nombreux cas d'utilisation de tuples nommés seront mieux servis par les classes de données. Mais pour citer l'excellent Why not namedtuples : Si vous voulez un tuple avec des noms, par tous les moyens: optez pour un namedtuple
Wolfgang Kuehn
1
En utilisant des classes de données, il n'est pas possible de déconstruire l'objet résultant comme vous le
feriez avec
6
Un tuple est immuable. Une classe de données ne l'est pas (par défaut). Elle a l'indicateur gelé qui se rapproche du comportement du tuple. Juste quelque chose dont il faut être conscient.
shao.lo
103

Vous pouvez utiliser typing.NamedTuple

À partir des documents

Version typée de namedtuple.

>>> import typing
>>> Point = typing.NamedTuple("Point", [('x', int), ('y', int)])

Ceci n'est présent que dans Python 3.5 et les versions ultérieures

Bhargav Rao
la source
Je l'ai déclaré comme ceci: GeoPoint = NamedTuple('GeoPoint', [('longitude', float), ('latitude', float)])alors j'essaie geo = GeoPoint (** data) où les données sont dict contenant les clés et les valeurs nécessaires decimal.Decimal, et aucune conversion à flotter ne se produit; (aucune erreur de type non plus :( :( alors comment cela typing.NamedTuplefonctionne? Voir l' essentiel .github.com / andilabs / 15002176b2bda786b9037077fa06cc71
andilabs
8
Le typage @andi n'applique pas ou ne transforme pas les variables, afaik.
Bhargav Rao