it-swarm.dev

Warum lösen Iteratoren in Python eine Ausnahme aus?

Hier ist die Syntax für Iteratoren in Java (etwas ähnliche Syntax in C #):

Iterator it = sequence.iterator();

while (it.hasNext()) {
    System.out.println(it.next());
}

Was Sinn macht. Hier ist die äquivalente Syntax in Python:

it = iter(sequence)
while True:
    try:
        value = it.next() 
    except StopIteration:
        break
    print(value)

Ich dachte, Ausnahmen sollten nur unter außergewöhnlichen Umständen verwendet werden.

Warum verwendet Python Ausnahmen, um die Iteration zu stoppen?

48

Es gibt eine sehr pythonische Möglichkeit, diesen Ausdruck zu schreiben, ohne explizit einen Try-Except-Block für ein StopIteration zu schreiben:

# some_iterable is some collection that can be iterated over
# e.g., a list, sequence, dict, set, itertools.combination(...)

for value in some_iterable:
    print(value)

Sie können sich über die relevanten PEPs 234255 informieren, wenn Sie mehr darüber erfahren möchten, warum StopIteration eingeführt wurde und welche Logik hinter Iteratoren steckt.

Ein allgemeines Prinzip in python ist, eine Möglichkeit zu haben, etwas zu tun (siehe import this), Und vorzugsweise seine schöne, explizite, lesbare und einfache, die die Pythonic-Methode erfüllt. Ihr äquivalenter Code ist nur erforderlich, da python gibt Iteratoren keine hasNext -Mitgliedsfunktion; es wird bevorzugt, dass Benutzer die Iteratoren direkt durchlaufen (und wenn Sie etwas anderes tun müssen) um es einfach zu lesen und eine Ausnahme zu machen).

Dieses automatische Abfangen einer StopIteration - Ausnahme am Ende eines Iterators ist sinnvoll und ein Analogon zum EOFError, das ausgelöst wird, wenn Sie über ein Dateiende hinaus lesen.

50
dr jimbob

Der Grund, warum python eine Ausnahme verwendet, um eine Iteration zu stoppen, ist in PEP 234 dokumentiert:

Es wurde in Frage gestellt, ob eine Ausnahme zum Signalisieren des Endes der Iteration nicht zu teuer ist. Es wurden verschiedene Alternativen für die StopIteration-Ausnahme vorgeschlagen: ein spezieller Wert End, um das Ende zu signalisieren, eine Funktion end (), um zu testen, ob der Iterator beendet ist, und sogar die IndexError-Ausnahme wiederzuverwenden.

  • Ein spezieller Wert hat das Problem, dass, wenn eine Sequenz jemals diesen speziellen Wert enthält, eine Schleife über diese Sequenz ohne Warnung vorzeitig endet. Wenn uns die Erfahrung mit nullterminierten C-Zeichenfolgen nicht die Probleme beigebracht hat, die dies verursachen kann, stellen Sie sich die Probleme vor, die ein Introspektionstool Python haben würde, wenn eine Liste aller integrierten Namen durchlaufen würde, vorausgesetzt, der spezielle Endwert war ein eingebauter Name!

  • Das Aufrufen einer end () - Funktion würde zwei Aufrufe pro Iteration erfordern. Zwei Anrufe sind viel teurer als ein Anruf plus ein Test für eine Ausnahme. Insbesondere die zeitkritische for-Schleife kann für eine Ausnahme sehr billig getestet werden.

  • Die Wiederverwendung von IndexError kann zu Verwirrung führen, da es sich um einen echten Fehler handeln kann, der durch vorzeitiges Beenden der Schleife maskiert wird.

Hinweis: Die idiomatische python Methode zum Durchlaufen einer Sequenz lautet wie folgt:

for value in sequence:
    print (value)
28
lesmana

Es ist ein Unterschied in der Philosophie. Die pythonische Designphilosophie lautet EAFP :

Es ist einfacher, um Vergebung zu bitten als um Erlaubnis. Dieser allgemeine Codierungsstil Python setzt die Existenz gültiger Schlüssel oder Attribute voraus und fängt Ausnahmen ab, wenn sich die Annahme als falsch herausstellt. Dieser saubere und schnelle Stil ist durch das Vorhandensein vieler try und gekennzeichnet except Anweisungen. Die Technik steht im Gegensatz zum Stil [~ # ~] lbyl [~ # ~] gemeinsam mit vielen anderen Sprachen wie C ...

20

Es ist nur so, dass die Java -Implementierung eine hasNext() -Methode hat, sodass Sie nach einem leeren Iterator suchen können, bevor Sie eine next() ausführen. Wenn Sie aufrufen next() auf einem Java Iterator ohne verbleibende Elemente, ein NoSuchElementException wird ausgelöst .

So effektiv können Sie einen Versuch machen ... fangen Sie in Java wie der Versuch ... außer in Python. Und ja, gemäß einer vorherigen Antwort lautet die Philosophie ) sehr wichtig in der pythonischen Welt.

7
yati sagade