Was macht das Ellipsis-Objekt?


539

Während ich untätig im Namespace surfte, bemerkte ich ein seltsam aussehendes Objekt namens Ellipsis, es scheint nichts Besonderes zu sein oder zu tun, aber es ist ein global verfügbares integriertes Objekt.

Nach einer Suche fand ich heraus, dass es in einer obskuren Variante der Slicing-Syntax von Numpy und Scipy verwendet wird ... aber fast nichts anderes.

Wurde dieses Objekt speziell zur Unterstützung von Numpy + Scipy zur Sprache hinzugefügt? Hat Ellipse überhaupt eine generische Bedeutung oder Verwendung?

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


19
Ich fand es so: Ich trat ein x=[];x.append(x);print(x), um zu sehen, wie es mit dem Stringing zyklischer Objekte umging. Es kehrte zurück [[...]]. Ich dachte: "Ich frage mich, was passiert, wenn ich tippe [[...]]? Ich vermute, es würde einen Syntaxfehler auslösen. Stattdessen kehrte er zurück [[Ellipsis]]. Python ist so seltsam. Die darauf folgende Google-Suche brachte mich auf diese Seite.
Cyoce

22
Beachten Sie, dass der ...in einem rekursiven Repr nur ein Platzhalter ist und keine Beziehung zuEllipsis
Eevee

16
Ein dreifacher Punkt beim Import bedeutet "Import von zwei Paketen nach oben".
Mad Physicist

1
@croq stackoverflow.com/q/32395926/2988730 . stackoverflow.com/q/1054271/2988730 . Diese beiden sollten alles erklären, mit richtigen Links zu Dokumenten und PEP in den Antworten.
Mad Physicist

Antworten:


558

Dies kam kürzlich in einer anderen Frage auf . Ich werde von dort aus auf meine Antwort eingehen:

Ellipse ist ein Objekt, das in Slice-Notation angezeigt werden kann. Zum Beispiel:

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

Seine Interpretation hängt ausschließlich von dem ab, was die __getitem__Funktion implementiert und EllipsisObjekte dort sieht , aber seine Hauptverwendung (und beabsichtigte Verwendung) liegt in der numpy -Bibliothek eines Drittanbieters, die einen mehrdimensionalen Array-Typ hinzufügt. Da es mehr als eine Dimension gibt, wird das Schneiden komplexer als nur ein Start- und Stoppindex. Es ist nützlich, auch in mehreren Dimensionen schneiden zu können. Bei einem 4x4-Array würde der obere linke Bereich beispielsweise durch das Slice definiert [: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]])

In diesem Zusammenhang wird Ellipse hier verwendet, um einen Platzhalter für die übrigen nicht angegebenen Array-Dimensionen anzugeben. Denken Sie daran , als Hinweis auf die volle Scheibe [:]für alle Dimensionen in dem Spalte sie platziert wird, so dass für ein 3D - Array, a[...,0]ist das gleiche wie a[:,:,0]und 4d a[:,:,:,0], in ähnlicher Weise, a[0,...,0]ist a[0,:,:,0](mit jedoch vielen Doppelpunkten in der Mitte bildet die volle Zahl von Dimensionen im Array).

Interessanterweise kann in python3 das Ellipsis-Literal ( ...) außerhalb der Slice-Syntax verwendet werden, sodass Sie tatsächlich schreiben können:

>>> ...
Ellipsis

Abgesehen von den verschiedenen numerischen Typen, nein, ich glaube nicht, dass es verwendet wird. Soweit mir bekannt ist, wurde es nur für den Numpy-Gebrauch hinzugefügt und hat keine andere Kernunterstützung als die Bereitstellung des Objekts und der entsprechenden Syntax. Das Objekt, das dort war, erforderte dies nicht, aber die wörtliche "..." Unterstützung für Slices tat dies.


22
Es wird auch in PEP484-Typ-Hinweisen in Stub-Dateien verwendet
noɥʇʎԀʎzɐɹƆ

24
Nur für den Fall, dass jemand neugierig ist: Es wird auch im Standardbibliotheksmodul verwendet typing: z. B. Callable[..., int]um eine aufrufbare Datei intanzugeben, die eine ohne Angabe der Signatur zurückgibt , oder Tuple[str, ...]um ein homogenes Tupel variabler Länge von Zeichenfolgen anzugeben .
Anakhand

6
Zu Ihrer Information, das FastAPI-Framework (das für Python 3.6+ ist) verwendet es auch (jetzt). fastapi.tiangolo.com/tutorial/query-params-str-validations
Andrew Allaire

2
@ArtOfWarfare Sie haben vollkommen recht, und dies kommt von jemandem, der verbal "Auslassungspunkte" sagt, anstatt zwischen Sätzen nachzulassen.
PrimeRibeyeDeal

Ich habe das gefunden. Es scheint zu erscheinen, wenn Sie eine Selbstreferenz (Zirkelreferenz) in einer Liste a = [1, 2]; a[0] = a; print(a)erstellen : gibt [[...], 2]. Ist das das Gleiche oder eine andere Verwendung?
Bill

220

In Python 3 können Sie das Ellipsen-Literal ...als Platzhalter für Code verwenden:

def will_do_something():
    ...

Das ist keine Magie; Jeder Ausdruck kann verwendet werden anstelle von ...z.

def will_do_something():
    1

(Ich kann das Wort "sanktioniert" nicht verwenden, aber ich kann sagen, dass diese Verwendung von Guido nicht direkt abgelehnt wurde.)


181
In einer Halbkonvention sehe ich oft ...verwendet, wo Leute etwas angeben möchten, das sie später ausfüllen möchten (ein leerer 'todo'-Block) und passeinen Block bedeuten sollen, der keinen Code haben soll.
Gareth Latty

26
Python hat auch das NotImplementedLiteral, das nützlich ist, wenn Ihre unvollständige Funktion etwas Sinnvolles zurückgeben soll (anstatt Nonewie in Ihrem Beispiel). (Ein weiterer Anwendungsfall: Implementieren von arithmetischen Operationen )
zvyn

13
@zvyn Das ist kein Literal. Es ist nur ein Name. Zum Beispiel NotImplemented = 'something_else'ist Python gültig, aber es ... = 'something_else'ist ein Syntaxfehler.
wim

4
@zvyn Was ist, wenn beim Importieren dieses Moduls eine Ausnahme aufgetreten ist? :)
pizzapants184

7
@zvyn NotImplementedist keine Alternative zu None. Seine Verwendung ist eher eng. Siehe Dokumentation hier
Hans

69

Ab Python 3.5 und PEP484 wird die wörtliche Ellipse verwendet, um bestimmte Typen einer statischen Typprüfung zu kennzeichnen, wenn das Typisierungsmodul verwendet wird.

Beispiel 1:

Homogene Tupel beliebiger Länge können beispielsweise mit einem Typ und einer Ellipse ausgedrückt werden Tuple[int, ...]

Beispiel 2:

Es ist möglich, den Rückgabetyp eines aufrufbaren Objekts ohne Angabe der Aufrufsignatur zu deklarieren, indem die Liste der Argumente durch ein wörtliches Auslassungszeichen (drei Punkte) ersetzt wird:

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

46

Sie können auch die Ellipse verwenden, wenn Sie die erwartete Doctest- Ausgabe angeben :

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

9
Aber handelt es sich tatsächlich um das Ellipsis-Objekt? Ist es nicht nur eine Funktion des Doctest-Parsers / Matchers?
Akaihola

1
@akaihola Ich würde sagen, dass es tut, wie bei doctest.ELLIPSIS beschrieben . Ich ...gehe davon aus, dass die meisten, wenn nicht alle Verwendungen von syntaktisch sind und nicht usedas eigentliche Ellipsis-Objekt. Ist es nicht wirklich nichts anderes als ein handlicher Name für ein anpassungsfähiges Konzept?
Nealmcb

34

Aus der Python-Dokumentation :

Dieses Objekt wird üblicherweise beim Schneiden verwendet (siehe Slicings ). Es werden keine speziellen Operationen unterstützt. Es gibt genau ein Ellipsenobjekt namens Ellipse (ein eingebauter Name). type(Ellipsis)()produziert den Ellipsis-Singleton.

Es ist geschrieben als Ellipsisoder ....


25

Zusammenfassend ist Ellipsis ab Python 3 eine weitere Singleton-Konstante, die der Singleton-Konstante ähnelt None, jedoch ohne eine bestimmte beabsichtigte Verwendung ist. Bestehende Verwendungen umfassen:

  • In der Slice-Syntax, um das gesamte Slice in den verbleibenden Dimensionen darzustellen
  • In Typhinweisen, die nur einen Teil eines Typs angeben ( Callable[..., int]oder Tuple[str, ...])
  • Geben Sie in Typ-Stub-Dateien einen Standardwert an, ohne ihn anzugeben

Mögliche Verwendungen könnten sein:

  • Als Standardwert für Orte, an denen Noneeine gültige Option ist
  • Als Inhalt für eine Funktion haben Sie noch nicht implementiert

14

__getitem__minimales ...Beispiel in einer benutzerdefinierten Klasse

Wenn die Magie Syntax ...zu übergeben wird []in einer benutzerdefinierten Klasse, __getitem__()erhält ein EllipsisKlassenobjekt.

Die Klasse kann dann mit diesem Singleton-Objekt tun, was sie will.

Beispiel:

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)

Die in Python integrierte listKlasse gibt ihr die Semantik eines Bereichs, und jede vernünftige Verwendung sollte dies natürlich auch tun.

Persönlich würde ich mich in meinen APIs einfach davon fernhalten und stattdessen eine separate, explizitere Methode erstellen.

Getestet in Python 3.5.2 und 2.7.12.


Führen Sie dies mit dem Argument -O aus und Ihr Code wird immer ausgeführt; D
Moshevi


7

Wie von @ noɥʇʎԀʎzɐɹƆ und @phoenix erwähnt - Sie können es tatsächlich in Stub-Dateien verwenden. z.B

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

Weitere Informationen und Beispiele zur Verwendung dieser Auslassungspunkte finden Sie hier https://www.python.org/dev/peps/pep-0484/#stub-files


2

Die beabsichtigte Verwendung sollte nicht nur für diese Module von Drittanbietern sein. Es wird in der Python-Dokumentation nicht richtig erwähnt (oder vielleicht konnte ich das einfach nicht finden), aber die Auslassungspunkte ...werden in CPython tatsächlich an mindestens einer Stelle verwendet.

Es wird zur Darstellung unendlicher Datenstrukturen in Python verwendet. Ich bin auf diese Notation gestoßen, als ich mit Listen herumgespielt habe.

Weitere Informationen finden Sie in dieser Frage .


8
Verschiedene Dinge. Diese Frage fragt nach dem ellipsiseingebauten Typ und dem EllipsisObjekt. Die Darstellung unendlicher Datenstrukturen mit Ellipsen dient lediglich der Anzeige und hat nichts mit ellipsisTyp oder EllipsisObjekt zu tun .
chys

3
@chys Tatsächlich ist dies in geringem Umfang der Fall - Python- __repr__Zeichenfolgen sollen gültige Python-Ausdrücke sein -, wenn in der Sprache keine Auslassungspunkte vorhanden wären, wäre die Darstellung kein gültiger Ausdruck.
Gareth Latty

3
@Lattyware Nun, es ist wahr, das ursprüngliche Design so beabsichtigt. Es soll auch eval(repr(a))gleich sein a. Leider ist es in der Praxis von Zeit zu Zeit falsch, selbst bei eingebauten Typen. Probieren Sie es aus : a=[]; a.append(a); eval(repr(a)). repr(a)ist [[...]], ungültiger Ausdruck in Python 2. (In Python 3 ist es gültig, aber das Bewertungsergebnis ist etwas anderes, immer noch entgegen der ursprünglichen Absicht.)
chys

1

Das ist gleichwertig.

l=[..., 1,2,3]
l=[Ellipsis, 1,2,3]

...ist eine im Inneren definierte Konstante built-in constants.

Ellipse

Das gleiche wie das Auslassungsliteral "...". Spezieller Wert, der hauptsächlich in Verbindung mit der erweiterten Slicing-Syntax für benutzerdefinierte Container-Datentypen verwendet wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.