如何在Python中输入包含多个元素的元组?

Eze*_*año 6 python geometry python-typing

我正在试验该typing模块,我想知道如何正确输入像九角形(9 点多边形)这样的东西,它应该是元组而不是列表,因为它应该是不可变的。

在 2D 空间中,它会是这样的:

Point2D = Tuple[float, float]
Nonagon = Tuple[Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D]

nine_points: Nonagon = (
    (0.0, 0.0),
    (6.0, 0.0),
    (6.0, 2.0),
    (2.0, 2.0),
    (6.0, 5.0),
    (2.0, 8.0),
    (6.0, 8.0),
    (6.0, 10.0),
    (0.0, 10.0),
)
Run Code Online (Sandbox Code Playgroud)

是否有任何语法糖可以使 Nonagon 声明更短或更容易阅读?

这不是有效的Python,但我正在寻找与此类似的东西:

Nonagon = Tuple[*([Point2D] * 9)]  # Not valid Python
Run Code Online (Sandbox Code Playgroud)

或者使用NamedTuple

# Not properly detected by static type analysers
Nonagon = NamedTuple('Nonagon', [(f"point_{i}", Point2D) for i in range(9)])  
Run Code Online (Sandbox Code Playgroud)

这不是我想要的:

# Valid but allows for more and less than 9 points
Nonagon = Tuple[Point2D, ...]  
Run Code Online (Sandbox Code Playgroud)

我认为最合适的方法是这样的:

from typing import Annotated

# Valid but needs MinMaxLen and checking logic to be defined from scratch
Nonagon = Annotated[Point2D, MinMaxLen(9, 9)]  
Run Code Online (Sandbox Code Playgroud)

Eri*_*Jin 3

您可以使用该types模块。所有类型提示均来自types.GenericAlias.

来自文档:

表示 PEP 585 通用类型,
例如t = list[int]t.__origin__islistt.__args__is (int,)

这意味着您可以通过将类型参数传递给类本身来创建自己的类型提示。

>>> Point2D = tuple[float, float]
>>> Nonagon = types.GenericAlias(tuple, (Point2D,)*9)
>>> Nonagon
tuple[tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float], tuple[float, float]]
Run Code Online (Sandbox Code Playgroud)