Obwohl dies das Standardverhalten in Python-Versionen bis einschließlich 3.6 ist, wird es in der Sprache als Fehler angesehen und soll in Python 3.7 geändert werden, sodass stattdessen eine Ausnahme ausgelöst wird.
Wie PEP 479 sagt:
Die Wechselwirkung von Generatoren und StopIteration
derzeit etwas überraschend ist, und obskuren Fehler verbergen kann. Eine unerwartete Ausnahme sollte nicht zu einem geringfügig veränderten Verhalten führen, sondern zu einem verrauschten und leicht zu debuggenden Traceback führen. Gegenwärtig wird StopIteration
, das versehentlich innerhalb einer Generatorfunktion ausgelöst wird, als das Ende der Iteration durch das Schleifenkonstrukt interpretiert, das den Generator antreibt.
Ab Python 3.5 ist es möglich, das Standardverhalten auf das für 3.7 geplante zu ändern. Dieser Code:
# gs_exc.py
from __future__ import generator_stop
def error():
return next(i for i in range(3) if i==10)
all(error() for i in range(2))
... stellt sich die folgende Ausnahme:
Traceback (most recent call last):
File "gs_exc.py", line 8, in <genexpr>
all(error() for i in range(2))
File "gs_exc.py", line 6, in error
return next(i for i in range(3) if i==10)
StopIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "gs_exc.py", line 8, in <module>
all(error() for i in range(2))
RuntimeError: generator raised StopIteration
In Python 3.5 und 3.6 ohne die __future__
Import, wird eine Warnung ausgelöst wird.Zum Beispiel:
# gs_warn.py
def error():
return next(i for i in range(3) if i==10)
all(error() for i in range(2))
$ python3.5 -Wd gs_warn.py
gs_warn.py:6: PendingDeprecationWarning: generator '<genexpr>' raised StopIteration
all(error() for i in range(2))
$ python3.6 -Wd gs_warn.py
gs_warn.py:6: DeprecationWarning: generator '<genexpr>' raised StopIteration
all(error() for i in range(2))
Das gleiche geschieht in Python 3. – khelwood
@khelwood Dank, werde ich das py2.7 Tag – amwinter
Natürlich entfernen. [** all ** * (iterable) * Gibt True zurück, wenn alle Elemente des Iterables wahr sind *** (oder wenn das Iterable leer ist) ***.] (https://docs.python.org/2/ library/functions.html # all) –