Введите подсказки в namedtuple

127

Рассмотрим следующий фрагмент кода:

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

Приведенный выше код - это всего лишь способ продемонстрировать, чего я пытаюсь достичь. Я хотел бы сделать namedtupleс подсказками типа.

Знаете ли вы какой-нибудь изящный способ добиться желаемого результата?

Павел Ханпарь
источник
2
Кроме того, начиная с py3.7 у вас есть опция dataclass
JohnE

Ответы:

151

Предпочтительный синтаксис для типизированного именованного кортежа с версии 3.6:

from typing import NamedTuple

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

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

Редактировать Начиная с Python 3.7, рассмотрите возможность использования dataclasses(ваша IDE может еще не поддерживать их для проверки статического типа):

from dataclasses import dataclass

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

Point(3)  # -> Point(x=3, y=1)
Вольфганг Кюн
источник
12
@JohnE; OP специально запросил именованные кортежи. Да, во многих случаях использования именованных кортежей лучше подходят классы данных. Но процитируем превосходную книгу «Почему не именованные кортежи» : если вам нужен кортеж с именами, во что бы то ни стало: выберите именованный кортеж
Вольфганг Кюн
1
Используя классы данных, невозможно деконструировать получившийся объект, как вы могли бы сделать Tuple
VARAK
6
Кортеж неизменен. Класс данных не имеет (по умолчанию) флаг замороженного состояния, который приближается к поведению кортежа. Просто то, о чем нужно знать.
shao.lo 02
103

Ты можешь использовать typing.NamedTuple

Из документов

Введенная версию о namedtuple.

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

Это присутствует только в Python 3.5 и новее.

Бхаргав Рао
источник
Я объявил это так: GeoPoint = NamedTuple('GeoPoint', [('longitude', float), ('latitude', float)])затем я пробую geo = GeoPoint (** data), где data - это dict, содержащий необходимые ключи и значения decimal.Decimal, и никакого преобразования в float не происходит; (тоже нет typerror :( :( так как это typing.NamedTupleработает? См. Суть .github.com / andilabs / 15002176b2bda786b9037077fa06cc71
andilabs
8
Типизация @andi не применяет и не приводит переменные, afaik.
Бхаргав Рао