在namedtuple中输入提示

Pav*_*ari 100 python type-hinting namedtuple python-3.x python-dataclasses

请考虑以下代码:

from collections import namedtuple
point = namedtuple("Point", ("x:int", "y:int"))
Run Code Online (Sandbox Code Playgroud)

上面的代码只是一种证明我想要实现的目标的方法.我想namedtuple用类型提示.

你知道如何达到预期效果的优雅方式吗?

Wol*_*ehn 105

从3.6开始的类型命名元组的首选语法是

from typing import NamedTuple

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

Point(3)  # -> Point(x=3, y=1)
Run Code Online (Sandbox Code Playgroud)

编辑 启动Python 3.7,考虑使用数据类(您的IDE可能尚不支持它们进行静态类型检查):

from dataclasses import dataclass

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

Point(3)  # -> Point(x=3, y=1)
Run Code Online (Sandbox Code Playgroud)

  • 元组是不可变的。数据类不是(默认情况下)它确实具有接近元组行为的冻结标志。只是需要注意一些事情。 (11认同)
  • @JohnE; OP专门询问命名元组。是的,通过数据类可以更好地服务于命名元组的许多用例。但是要引用出色的[为什么不命名元组](http://www.attrs.org/en/stable/why.html#namedtuples):_如果您想要一个带有名称的元组,则一定要:选择一个namedtuple_ (7认同)
  • 数据类不可订阅,并且在迭代时也不能像命名元组那样解包,因此我认为它们远非完美的替代方案。 (6认同)
  • 如果 dataclass 适合您,您可以进一步使用 [pydantic](https://pydantic-docs.helpmanual.io/) 包以优雅的方式在运行时强制执行类型检查。 (4认同)
  • 使用数据类,不可能像元组那样解构结果对象 (3认同)

Bha*_*Rao 95

您可以使用 typing.NamedTuple

来自文档

类型版本namedtuple.

>>> import typing
>>> Point = typing.NamedTuple("Point", [('x', int), ('y', int)])
Run Code Online (Sandbox Code Playgroud)

这只出现在Python 3.5之后

  • 在较新的版本中,您可以将 NamedTuple 声明为 `Point = Typing.NamedTuple("Point", x=int, y=int)`,这样更简洁、更短。 (14认同)
  • @andi打字不会强制执行或转换变量,afaik. (8认同)
  • ^ 有关此语法的文档、讨论和示例几乎不存在。我只在[cpython Typing.py文件](https://github.com/python/cpython/blob/d7a5aca982def155a9255893cefcc1493c127c9c/Lib/typing.py#L2408)中找到它。它声明该语法可从 3.6+ 开始使用,并且至少在 3.7+ 代码中可用。尽管似乎没有更清晰的版本来设置与成员/类型声明相邻的默认值。 (2认同)

mrv*_*vol 15

公平地说,NamedTuple来自typing

>>> from typing import NamedTuple
>>> class Point(NamedTuple):
...     x: int
...     y: int = 1  # Set default value
...
>>> Point(3)
Point(x=3, y=1)
Run Code Online (Sandbox Code Playgroud)

等于经典namedtuple

>>> from collections import namedtuple
>>> p = namedtuple('Point', 'x,y', defaults=(1, ))
>>> p.__annotations__ = {'x': int, 'y': int}
>>> p(3)
Point(x=3, y=1)
Run Code Online (Sandbox Code Playgroud)

所以,NamedTuple这只是语法糖namedtuple

NamedTuple下面,您可以从 的源代码中找到一个创建函数python 3.10。正如我们所看到的,它使用collections.namedtuple构造函数并__annotations__从提取的类型中添加:

def _make_nmtuple(name, types, module, defaults = ()):
    fields = [n for n, t in types]
    types = {n: _type_check(t, f"field {n} annotation must be a type")
             for n, t in types}
    nm_tpl = collections.namedtuple(name, fields,
                                    defaults=defaults, module=module)
    nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = types
    return nm_tpl
Run Code Online (Sandbox Code Playgroud)