[PYTHON] Erfassen Sie GeneratorExit und erkennen Sie das Ende der Iteration von der Generatorseite

Der Iterator selbst dreht sich möglicherweise nicht aufgrund von "break" usw. zum Ende, aber es gibt seltene Fälle, in denen Sie die Iteration im Generator zum Ende drehen möchten.

Beispiele, die nicht funktionieren

Als Beispiel fügt das folgende "range_printsum" den Vorgang des Druckens der Summe des Bereichs zur Funktion "range" hinzu.

gen.py


def range_printsum(*args, **kwargs):
    sum_ = 0

    for i in range(*args, **kwargs):
        sum_ += i
        yield i

    print(sum_)

Wenn in dieser Generatorimplementierung die Iteration in der Mitte gestoppt wird, ist das, was tatsächlich in "sum_" gespeichert ist, die Gesamtzahl der "Erträge", und "sum_" wird überhaupt nicht ausgegeben.

>>> from gen import range_printsum
>>> for i in range_printsum(11):
...     pass
...
55
>>> for i in range_printsum(11):
...     if i > 5:
...         break
...
>>>

Beispiele, die funktionieren

Erfassen Sie also "Generator Exit". Dies wird gesendet, wenn der Generator geschlossen ist (wenn der Generator close () aufgerufen wird). Dies kann auch dann erfasst werden, wenn die Schleife wie "for" unterbrochen ist. Ändern Sie nach der Erfassung von "GeneratorExit" "range_printsum" so, dass kein Wert zurückgegeben und nur addiert wird.

gen.py


def range_printsum(*args, **kwargs):
    sum_ = 0
    stop_yield = False

    for i in range(*args, **kwargs):
        sum_ += i
        if not stop_yield:
            try:
                yield i
            except GeneratorExit:
                stop_yield = True

    print(sum_)

Diesmal funktioniert es wie erwartet.

>>> from gen import range_printsum
>>> for i in range_printsum(11):
...     pass
...
55
>>> for i in range_printsum(11):
...     if i > 5:
...         break
...
55
>>>

Es funktioniert auch, wenn es so unterbrochen wird.

>>> try:
...     for i in range_printsum(11):
...         if i > 5:
...             raise IndexError
... except IndexError:
...     pass
...
55
>>>

Als Einschränkung der Generatorspezifikationen darf ein einmal geschlossener Generator keinen Wert erzeugen. Wenn Sie nach der Erfassung des "GeneratorExit" einen Wert "ergeben", wird der Fehler "RuntimeError: Generator ignoriert GeneratorExit" angezeigt.

Recommended Posts

Erfassen Sie GeneratorExit und erkennen Sie das Ende der Iteration von der Generatorseite
Der Operator und des Python-Bewertungsausdrucks scheint vom Ausdruck auf der linken Seite ausgewertet zu werden
Othello ~ Aus der dritten Zeile von "Implementation Deep Learning" (4) [Ende]
DJango Hinweis: Von Anfang an (Vereinfachung und Aufteilung von URLConf)
Kombination von rekursiv und Generator
Betreiben Sie Firefox mit Selen aus Python und speichern Sie die Bildschirmaufnahme
Finden Sie die Entfernung von Breite und Länge (unter Berücksichtigung der Rundheit der Erde).
Finden Sie den Wegpunkt aus dem Breiten- und Längengrad (unter Berücksichtigung der Rundheit der Erde).
Die Geschichte von Python und die Geschichte von NaN
Existenz aus Sicht von Python
Ermitteln Sie mit NumPy die Trägheitsspindel und das Hauptträgheitsmoment aus dem Trägheitstensor
Fassen Sie den Titel von Hottentori in Hateb zusammen und schauen Sie sich die Gegenwart des Web an