如何在 Python 中键入包含许多元素的元组?
How to type a Tuple with many elements in Python?
我正在试验 typing
模块,我想知道如何正确输入像 Nonagon(9 点多边形)这样的东西,它应该是元组而不是列表,因为它应该是不可变的.
在 2D 中 space,它会是这样的:
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),
)
是否有任何语法糖可以使 Nonagon 声明更短或更易于阅读?
这无效 Python,但我正在寻找与此类似的内容:
Nonagon = Tuple[*([Point2D] * 9)] # Not valid Python
或使用NamedTuple
# Not properly detected by static type analysers
Nonagon = NamedTuple('Nonagon', [(f"point_{i}", Point2D) for i in range(9)])
这不是我想要的:
# Valid but allows for more and less than 9 points
Nonagon = Tuple[Point2D, ...]
我认为最合适的方法是:
from typing import Annotated
# Valid but needs MinMaxLen and checking logic to be defined from scratch
Nonagon = Annotated[Point2D, MinMaxLen(9, 9)]
不确定这是否适合您的目的,但 numpy 在这里可能会有用。
import numpy as np
ones = np.ones(9)
nonogon = ones * Point2D
您描述的第一种方式:
Nonagon = Tuple[Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D]
是正确的方法,如 2016 python/typing 期中所讨论的那样。是的,它有点难看,但你只需要定义一次。
您可以在此处利用 Annotated
,但这最终取决于您的类型检查器是否可以使用您包含的注释。并非所有类型检查器都必须使用这些注释,而拼写出元组中应包含多少个元素是每个(正常运行的)类型检查器都应该识别的内容。
您可以使用types
模块。所有类型提示均来自 types.GenericAlias
.
来自文档:
Represent a PEP 585 generic type
E.g. for t = list[int]
, t.__origin__
is list
and t.__args__
is (int,)
.
这意味着您可以通过将类型参数传递给 class 本身来创建自己的类型提示。
>>> 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]]
我正在试验 typing
模块,我想知道如何正确输入像 Nonagon(9 点多边形)这样的东西,它应该是元组而不是列表,因为它应该是不可变的.
在 2D 中 space,它会是这样的:
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),
)
是否有任何语法糖可以使 Nonagon 声明更短或更易于阅读?
这无效 Python,但我正在寻找与此类似的内容:
Nonagon = Tuple[*([Point2D] * 9)] # Not valid Python
或使用NamedTuple
# Not properly detected by static type analysers
Nonagon = NamedTuple('Nonagon', [(f"point_{i}", Point2D) for i in range(9)])
这不是我想要的:
# Valid but allows for more and less than 9 points
Nonagon = Tuple[Point2D, ...]
我认为最合适的方法是:
from typing import Annotated
# Valid but needs MinMaxLen and checking logic to be defined from scratch
Nonagon = Annotated[Point2D, MinMaxLen(9, 9)]
不确定这是否适合您的目的,但 numpy 在这里可能会有用。
import numpy as np
ones = np.ones(9)
nonogon = ones * Point2D
您描述的第一种方式:
Nonagon = Tuple[Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D]
是正确的方法,如 2016 python/typing 期中所讨论的那样。是的,它有点难看,但你只需要定义一次。
您可以在此处利用 Annotated
,但这最终取决于您的类型检查器是否可以使用您包含的注释。并非所有类型检查器都必须使用这些注释,而拼写出元组中应包含多少个元素是每个(正常运行的)类型检查器都应该识别的内容。
您可以使用types
模块。所有类型提示均来自 types.GenericAlias
.
来自文档:
Represent a PEP 585 generic type
E.g. fort = list[int]
,t.__origin__
islist
andt.__args__
is(int,)
.
这意味着您可以通过将类型参数传递给 class 本身来创建自己的类型提示。
>>> 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]]