Behandeln einer Ausnahme in einem generator
Habe ich einen generator und eine Funktion, verbraucht es:
def read():
while something():
yield something_else()
def process():
for item in read():
do stuff
Wenn der generator löst eine Ausnahme aus, ich will Prozess, der in der Verbraucher-Funktion und dann weiter konsumieren der iterator, bis es erschöpft ist. Beachten Sie, dass ich wollen nicht zu haben, jede exception-handling-code in den generator.
Ich dachte an etwas wie:
reader = read()
while True:
try:
item = next(reader)
except StopIteration:
break
except Exception as e:
log error
continue
do_stuff(item)
das sieht aber eher unangenehm für mich.
InformationsquelleAutor georg | 2012-07-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn ein generator eine Ausnahme auslöst, wird er beendet. Man kann nicht mehr verbrauchen die Elemente, die es erzeugt.
Beispiel:
Wenn Sie Steuern den generator-code, können Sie die Ausnahme behandeln im inneren des Generators; wenn nicht, sollten Sie versuchen zu vermeiden, eine Ausnahme Auftritt.
InformationsquelleAutor Sven Marnach
Dies ist auch etwas, das ich nicht sicher bin, wenn ich mit richtig/aus.
Was ich mache ist
yield
eineException
aus dem generator, und dann heben Sie es irgendwo anders. Wie:Diese Weise habe ich immer noch tragen, über die Ausnahme, ohne dass es, die würde, die den generator-Funktion zu stoppen. Der große Nachteil ist, dass ich brauche, um zu überprüfen, das ergab das Ergebnis mit
isinstance
bei jeder iteration. Ich weiß nicht, wie ein generator, können zu Ergebnissen führen, die von verschiedenen Arten, aber verwenden Sie es als letzten Ausweg.Danke @georg für den Hinweis auf diese Antwort. Was ein
tuple
mitException
ist, glaube ich, eine bessere Lösung.InformationsquelleAutor dojuba
Habe ich gebraucht um dieses problem zu lösen, ein paar mal und kam auf diese Frage nach einer Suche nach dem, was andere Menschen getan haben.
Werfen statt Erhöhen
Eine option - das erfordert die Umgestaltung ein wenig - wäre
throw
Ausnahme in den generator (auf ein anderes error-handling-generator) eher alsraise
. Hier ist, was das Aussehen könnte:Dies ist nicht immer die beste Lösung zu sein, aber es ist sicherlich eine option.
Verallgemeinerte Lösung
Könnten Sie machen alles nur ein bisschen schöner mit einem decorator:
Ausgabe:
Aber der Nachteil ist Sie haben noch zu setzen haben Generika
Exception
Handhabung im inneren des Generators, erzeugt möglicherweise Fehler. Es ist nicht möglich, dies zu umgehen, da die Anhebung jede exception, die in einem generator zu schließen.Kernel von einer Idee
Wäre es schön, irgendeine Art
yield raise
Aussage, die erlaubt, dass der generator weiter läuft, wenn es kann, nachdem der Fehler geworfen wurde. Dann könnten Sie code schreiben:...und die
handler()
Dekorator könnte wie folgt Aussehen:Ja, ich habe nicht sah bei dieser in eine Weile, aber du hast wahrscheinlich Recht über den decorator.
Festnetz; jetzt arbeiten.
InformationsquelleAutor Rick Teachey