python ellipsis

¿Qué hace el objeto Python Ellipsis?



(10)

A partir de Python 3.5 y PEP484 , los puntos suspensivos literales se usan para denotar ciertos tipos a un verificador de tipo estático cuando se usa el módulo de typing .

Ejemplo 1:

Las tuplas homogéneas de longitud arbitraria se pueden expresar utilizando un tipo y puntos suspensivos, por ejemplo Tuple[int, ...]

Ejemplo 2:

Es posible declarar el tipo de retorno de un llamable sin especificar la firma de la llamada sustituyendo un punto suspensivo literal (tres puntos) para la lista de argumentos:

def partial(func: Callable[..., str], *args) -> Callable[..., str]: # Body

Mientras navegaba ociosamente por el espacio de nombres, noté un objeto de aspecto extraño llamado " Ellipsis ", no parece ser ni hacer nada especial, pero es un componente integrado disponible a nivel mundial.

Después de una búsqueda, descubrí que Numpy y Scipy utilizan una variante oscura de la sintaxis de corte ... pero casi nada más.

¿Se agregó este objeto al lenguaje específicamente para admitir Numpy + Scipy? ¿Ellipsis tiene algún significado o uso genérico?

D:/workspace/numpy>python Python 2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> Ellipsis Ellipsis


Como lo mencionaron @noɥʇʎԀʎzɐɹƆ y @phoenix - De hecho, puede usarlo en archivos de código auxiliar. p.ej

class Foo: bar: Any = ... def __init__(self, name: str=...) -> None: ...

Puede encontrar más información y ejemplos de cómo utilizar estos puntos suspensivos aquí https://www.python.org/dev/peps/pep-0484/#stub-files



En Python 3, puedes usar el literal de Ellipsis ... como un marcador de posición "nop" para el código:

def will_do_something(): ...

Esto no es magia; Se puede utilizar cualquier expresión en lugar de ... , por ejemplo:

def will_do_something(): 1

(No puedo usar la palabra "sancionado", pero puedo decir que Guido no rechazó de plano este uso).


Esto surgió en otra question recientemente. Voy a elaborar mi answer desde allí:

Ellipsis es un objeto que puede aparecer en notación de corte. Por ejemplo:

myList[1:2, ..., 0]

Su interpretación depende únicamente de lo que implemente la función __getitem__ y vea los objetos Ellipsis allí, pero su uso principal (y previsto) está en la extensión numérica de python , que agrega un tipo de matriz multidimensional. Dado que hay más de una dimensión, la segmentación se vuelve más compleja que solo un índice de inicio y detención; Es útil poder dividir en múltiples dimensiones también. Por ejemplo, dada una matriz de 4x4, el área superior izquierda se definiría mediante la división [:2,:2] :

>>> a array([[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12], [13, 14, 15, 16]]) >>> a[:2,:2] # top left array([[1, 2], [5, 6]])

Extendiendo esto, Ellipsis se usa aquí para indicar un marcador de posición para el resto de las dimensiones de la matriz no especificadas. Piense en ello como que indica la división completa [:] para todas las dimensiones en el espacio que se coloca, por lo que para una matriz 3d, a[...,0] es lo mismo que a[:,:,0] y para 4d, a[:,:,:,0] , de manera similar, a[0,...,0] es a[0,:,:,0] (con muchos colones en el medio, forman el número completo de dimensiones en la matriz).

Curiosamente, en python3, el literal de Ellipsis ( ... ) se puede usar fuera de la sintaxis de la porción, por lo que realmente puede escribir:

>>> ... Ellipsis

Aparte de los diversos tipos numéricos, no, no creo que se use. Por lo que yo sé, se agregó únicamente para uso numérico y no tiene soporte central más que proporcionar el objeto y la sintaxis correspondiente. El objeto que estaba allí no requería esto, pero el soporte literal "..." para los cortes lo hizo.



Resumiendo lo que otros han dicho, a partir de Python 3, Ellipsis es esencialmente otra constante de singleton similar a None , pero sin un uso específico en particular. Los usos existentes incluyen:

  • En la sintaxis de división para representar la división completa en las dimensiones restantes
  • En la sugerencia de tipo para indicar solo parte de un tipo ( Callable[..., int] o Tuple[str, ...] )
  • En archivos de código auxiliar de tipo para indicar que hay un valor predeterminado sin especificarlo

Los posibles usos podrían incluir:

  • Como valor predeterminado para los lugares donde None es una opción válida
  • Como el contenido de una función que aún no has implementado.

Su uso previsto no debe ser solo para estos módulos de terceros. No se menciona correctamente en la documentación de Python (o tal vez simplemente no pude encontrarlo) pero los puntos suspensivos ... realidad se usan en CPython en al menos un lugar.

Se utiliza para representar estructuras de datos infinitas en Python. Me encontré con esta notación jugando con listas.

Vea esta pregunta para más información.


También puede utilizar la elipsis cuando especifique doctest resultado doctest esperado:

class MyClass(object): """Example of a doctest Ellipsis >>> thing = MyClass() >>> # Match <class ''__main__.MyClass''> and <class ''%(module).MyClass''> >>> type(thing) # doctest:+ELLIPSIS <class ''....MyClass''> """ pass


__getitem__ minimal ... ejemplo en una clase personalizada

... sirve como un valor mágico de clase singleton que se pasa a __getitem__ cuando usas la sintaxis "mágica" ...

La clase puede hacer lo que quiera con ella.

Ejemplo:

class C(object): def __getitem__(self, k): return k # Single argument is passed directly. assert C()[0] == 0 # Multiple indices generate a tuple. assert C()[0, 1] == (0, 1) # Slice notation generates a slice object. assert C()[1:2:3] == slice(1, 2, 3) # Ellipsis notation generates the Ellipsis class object. # Ellipsis is a singleton, so we can compare with `is`. assert C()[...] is Ellipsis # Everything mixed up. assert C()[1, 2:3:4, ..., 6] == (1, slice(2,3,4), Ellipsis, 6)

La clase de list incorporada de Python elige darle la semántica de un rango, y cualquier uso sensato de la misma debería, por supuesto, también.

Personalmente, me mantendría alejado de él en mis API y, en su lugar, crearía un método separado y más explícito.