Estoy experimentando con el módulo de typing y quería saber cómo escribir correctamente algo como un nonágono (un polígono de 9 puntos), que debería ser una tupla y no una lista porque debería ser inmutable.
En el espacio 2D, sería algo como esto:
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), )¿Hay algún azúcar sintáctico disponible para hacer que la declaración de Nonagon sea más corta o más fácil de leer?
Esto no es Python válido, pero estoy buscando algo similar a esto:
Nonagon = Tuple[*([Point2D] * 9)] # Not valid Python O usando NamedTuple
# Not properly detected by static type analysers Nonagon = NamedTuple('Nonagon', [(f"point_{i}", Point2D) for i in range(9)])Esto no es lo que quiero:
# Valid but allows for more and less than 9 points Nonagon = Tuple[Point2D, ...]Creo que la forma más adecuada sería algo como:
from typing import Annotated # Valid but needs MinMaxLen and checking logic to be defined from scratch Nonagon = Annotated[Point2D, MinMaxLen(9, 9)]La primera forma en que lo describiste:
Nonagon = Tuple[Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D, Point2D]es la forma correcta de hacerlo, como se discutió en un problema de escritura/python de 2016. Sí, es un poco feo, pero solo hay que definirlo una vez.
Puede aprovechar Annotated aquí, pero en última instancia depende de si su verificador de tipos puede hacer uso de las anotaciones que incluye. No todos los verificadores de tipos necesariamente harían uso de esas anotaciones, mientras que deletrear cuántos elementos deben estar en la tupla es algo que todo verificador de tipos (en funcionamiento) debería reconocer.
Puede utilizar el módulo de types . Todas las sugerencias de tipo provienen de types.GenericAlias .
Del documento:
Representa un tipo genérico PEP 585
Por ejemplo, parat = list[int],t.__origin__eslistyt.__args__is(int,).
Esto significa que puede crear su propia sugerencia de tipo pasando los argumentos de tipo a la clase misma.
>>> 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]]No estoy seguro de si esto funcionaría para sus propósitos, pero numpy podría ser útil aquí.
import numpy as np ones = np.ones(9) nonogon = ones * Point2D