如何在Python中键入许多元素?

发布于 2025-01-23 16:34:17 字数 1287 浏览 1 评论 0原文

我正在尝试键入模块,我想知道如何正确键入诸如nonagr(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),
)

是否有任何句法糖可以使NONAGRAGAR声明更短或更易于阅读?

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

Nonagon = Tuple[*([Point2D] * 9)]  # Not valid Python

或使用nequ tumeTuple

# 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)]  

I am experimenting with the typing module and I wanted to know how to properly type something like a Nonagon (a 9 point polygon), which should be a Tuple and not a List because it should be immutable.

In 2D space, it would be something like this:

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),
)

Is there any syntactic sugar available to make the Nonagon declaration shorter or easier to read?

This is not valid Python, but I am looking for something similar to this:

Nonagon = Tuple[*([Point2D] * 9)]  # Not valid Python

Or using NamedTuple

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

This is NOT what I want:

# Valid but allows for more and less than 9 points
Nonagon = Tuple[Point2D, ...]  

I think the most adequate way would be something like:

from typing import Annotated

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

牵你的手,一向走下去 2025-01-30 16:34:17

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

从文档:

代表PEP 585通用类型
例如t = list [int]t。 (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]]

You can use the types module. All type hints come from types.GenericAlias.

From the doc:

Represent a PEP 585 generic type
E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).

This means that you can make your own type hinting by passing the type arguments to the class itself.

>>> 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]]
染墨丶若流云 2025-01-30 16:34:17

您描述它的第一种方法

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

是:正确的方法,如2016年 python /打字问题。是的,这有点丑陋,但是您只需要定义一次即可。

您可以在此处利用注释,但最终取决于您的Typechecker是否可以利用您包含的注释。并非所有Typechecker都必须使用这些注释,而拼写元组中应有的元素是每个(功能)Typechecker应该识别的。

The very first way you described it:

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

is the right way to do it, as discussed in a 2016 python/typing issue. Yes, it's a bit ugly, but you only have to define it once.

You could leverage Annotated here, but it ultimately depends on whether your typechecker can make use of the annotations that you include. Not all typecheckers would necessarily make use of those annotations, whereas spelling out how many elements should be in the tuple is something that every (functioning) typechecker should recognize.

暗地喜欢 2025-01-30 16:34:17

不确定这是否适合您的目的,但是Numpy在这里可能很有用。


import numpy as np
ones = np.ones(9)
nonogon = ones * Point2D

Not sure if this would work for your purposes, but numpy might be useful here.


import numpy as np
ones = np.ones(9)
nonogon = ones * Point2D

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文