Ja, es ist immer noch ein Generator. Das return
ist (fast) gleichbedeutend mit Erhöhen StopIteration
.
PEP 255 beschreibt es:
Spezifikation: Rückgabe
Eine Generatorfunktion kann auch return-Anweisungen der folgenden Form enthalten:
"return"
Beachten Sie, dass eine Ausdrucksliste für return-Anweisungen im Hauptteil eines Generators nicht zulässig ist (obwohl sie natürlich in den Hauptteilen von Nicht-Generator-Funktionen erscheinen können, die im Generator verschachtelt sind).
Wenn eine return-Anweisung gefunden wird, fährt die Steuerung wie bei jeder Funktionsrückgabe fort und führt die entsprechenden finally-Klauseln aus (falls vorhanden). Dann wird eine StopIteration-Ausnahme ausgelöst, die signalisiert, dass der Iterator erschöpft ist. Eine StopIteration-Ausnahme wird auch ausgelöst, wenn die Steuerung ohne explizite Rückgabe vom Ende des Generators ausgeht.
Beachten Sie, dass return sowohl für Generatorfunktionen als auch für Nicht-Generatorfunktionen "Ich bin fertig und habe nichts Interessantes zurückzugeben" bedeutet.
Beachten Sie, dass return nicht immer gleichbedeutend mit dem Auslösen von StopIteration ist: Der Unterschied besteht darin, wie einschließende try / Except-Konstrukte behandelt werden. Zum Beispiel,
>>> def f1():
... try:
... return
... except:
... yield 1
>>> print list(f1())
[]
weil, wie in jeder Funktion, return einfach beendet wird, aber
>>> def f2():
... try:
... raise StopIteration
... except:
... yield 42
>>> print list(f2())
[42]
weil StopIteration wie jede Ausnahme von einem bloßen "außer" erfasst wird.
return
einen Streit hätte?SyntaxError: 'return' with argument inside generator
. Es ist in Python 3.x zulässig, soll jedoch hauptsächlich mit Coroutinen verwendet werden. Sie führen asynchrone Aufrufe anderer Coroutinen mityield coroutine()
(oderyield from coroutine()
, abhängig vom verwendeten asynchronen Framework) durch und geben alles zurück, was Sie von der Coroutine zurückgeben möchten mitreturn value
. In Python 2.x müssen Sie einen Trick verwendenraise Return(value)
, um Werte von Coroutinen zurückzugeben.Ja, es ist immer noch ein Generator. Ein leeres
return
oderreturn None
kann verwendet werden, um eine Generatorfunktion zu beenden. Dies entspricht dem Erhöhen von aStopIteration
( Einzelheiten finden Sie in der Antwort von @ NPE ).Beachten Sie, dass eine Rückgabe mit Nicht-Keine-Argumenten
SyntaxError
in Python-Versionen vor 3.3 erfolgt.Wie @BrenBarn in Kommentaren ab Python 3.3 hervorhob, wird der Rückgabewert jetzt an übergeben
StopIteration.
Aus PEP 380 :
quelle
return
ein Argument hätte (außerNone
)?return
höher können Sie das Argument mit einem Argument an die angehobene StopIteration übergeben. Siehe diese Frage .asyncio
Modul basiert auf dieser Funktion (zusammen mit demyield from
Schlüsselwort).value = yield
usw. Die Einführung vonyield from
und die Fähigkeit,return
Werte von Generatoren zu erhalten, kam mit PEP 380 , die beide von genutzt werdenasyncio
. Sie können immer noch eine robuste Coroutine-Implementierung mit nur den Funktionen von PEP 343 haben. Das Schreiben ist nur ein wenig weniger sauber.Es gibt eine Möglichkeit, eine Yield- und Return-Methode in einer Funktion zu erreichen, mit der Sie einen Wert oder Generator zurückgeben können.
Es ist wahrscheinlich nicht so sauber, wie Sie es möchten, aber es macht das, was Sie erwarten.
Hier ist ein Beispiel:
def six(how_many=None): if how_many is None or how_many < 1: return None # returns value if how_many == 1: return 6 # returns value def iter_func(): for count in range(how_many): yield 6 return iter_func() # returns generator
quelle
Hinweis:
StopIteration
Mit dem folgenden Beispiel erhalten Sie keine Ausnahme.def odd(max): n = 0 while n < max: yield n n = n + 1 return 'done' for x in odd(3): print(x)
Aber Sie können es auf diese Weise fangen:
g = odd(3) while True: try: x = next(g) print(x) except StopIteration as e: print("g return value:", e.value) break
quelle