Seit Python 3.3, wenn eine Generatorfunktion einen Wert zurückgibt, wird dies der Wert für die StopIteration-Ausnahme, die ausgelöst wird. Dies kann auf verschiedene Arten gesammelt werden:
yield from
-Ausdrucks, der die umschließende Funktion impliziert, ist ebenfalls ein Generator. next()
oder .send()
in einem try / except-Block abwickeln. Wenn ich jedoch einfach den Generator in einer for-Schleife durchlaufen möchte - der einfachste Weg -, scheint es keine Möglichkeit zu geben, den Wert der StopIteration-Ausnahme und somit den Rückgabewert zu sammeln. Ich verwende ein einfaches Beispiel, in dem der Generator Werte liefert, und gibt am Ende eine Zusammenfassung zurück (laufende Summen, Durchschnittswerte, Zeitstatistiken usw.).
%Vor%Ein Weg ist, die Schleife selbst zu handhaben:
%Vor% Aber das wirft die Einfachheit der for-Schleife weg. Ich kann yield from
nicht verwenden, da dies erfordert, dass der aufrufende Code selbst ein Generator ist. Gibt es einen einfacheren Weg als die oben gezeigte Roll-Ones-for-Schleife?
Kombiniert man die Antworten von @Chad S. und @KT, scheint das einfachste meine Generatorfunktion in eine Klasse umzuwandeln, die das Iteratorprotokoll verwendet:
%Vor%Und @ Ferdinand Beyers Antwort ist am einfachsten, wenn ich den Wertproduzenten nicht umgestalten kann.
Sie können sich das value
-Attribut von StopIteration
(und möglicherweise StopIteration
selbst) als Implementierungsdetails vorstellen, das nicht für die Verwendung in "normalem" Code ausgelegt ist.
Schauen Sie sich PEP 380 an Das gibt das yield from
-Feature von Python 3.3 an: Es wird diskutiert, dass einige Alternativen zur Verwendung von StopIteration
, um den Rückgabewert zu übernehmen, berücksichtigt werden.
Da Sie den Rückgabewert in einer normalen for
-Schleife nicht erhalten sollen, gibt es keine Syntax dafür. Genauso wie Sie das StopIteration
nicht explizit abfangen sollen.
Eine nette Lösung für Ihre Situation wäre eine kleine Utility-Klasse (möglicherweise nützlich genug für die Standardbibliothek):
%Vor%Dies umschließt einen beliebigen Generator und fängt seinen Rückgabewert ein, um später untersucht zu werden:
%Vor%Ein einfacher Weg, den Rückgabewert zu handhaben (einer, der keine Hilfsklasse instanziiert), ist die Verwendung der Abhängigkeitsinjektion .
Das heißt, man kann die Funktion übergeben, um den Rückgabewert mit der folgenden Wrapper / Helfer-Generator-Funktion zu bearbeiten / zu bearbeiten:
%Vor%Zum Beispiel das folgende -
%Vor%führt zu -
%Vor%