palabras iteradores generadores generador funcion explicacion creacion codigo python generator stopiteration

python - iteradores - ¿Cuál es la diferencia entre el aumento de StopIteration y una declaración de retorno en los generadores?



python funcion yield (3)

Tengo curiosidad acerca de la diferencia entre usar raise StopIteration y una declaración de return en los generadores.

Por ejemplo, ¿hay alguna diferencia entre estas dos funciones?

def my_generator0(n): for i in range(n): yield i if i >= 5: return def my_generator1(n): for i in range(n): yield i if i >= 5: raise StopIteration

Supongo que la forma más "pirónica" de hacerlo es la segunda (por favor, corríjame si me equivoco), pero en la medida en que puedo ver ambas formas, generar una excepción StopIteration .


A finales de 2014, la return es correcta y el raise StopIteration para terminar un generador se encuentra en un raise StopIteration de depreciación. Ver PEP 479 para más detalles.

Resumen

Este PEP propone un cambio a los generadores: cuando StopIteration se StopIteration dentro de un generador, se reemplaza con RuntimeError . (Más precisamente, esto sucede cuando la excepción está a punto de desbordarse del marco de la pila del generador). Debido a que el cambio es incompatible con la __future__ , la función se introduce inicialmente con una declaración __future__ .

Aceptación

Este PEP fue aceptado por el BDFL el 22 de noviembre ...

Razón fundamental

La interacción de los generadores y StopIteration es actualmente algo sorprendente y puede ocultar errores ocultos. Una excepción inesperada no debería dar como resultado un comportamiento alterado sutilmente, sino que debería causar un rastreo ruidoso y fácilmente depurado. Actualmente, StopIteration originado accidentalmente dentro de una función del generador se interpretará como el final de la iteración por la construcción de bucle que impulsa el generador.

...


Es cierto, son equivalentes, excepto que uno es legible mientras que el otro es oscuro. Esto se remonta a la primera versión de los generadores (PEP 255, en "Especificación: Devolución"), y las mejoras posteriores de (como, por ejemplo, las rutinarias) no cambian esto. El yield from 3.3 yield from (PEP 380) extiende eso para return <expr> como azúcar sintáctica para raise StopIteration(<expr>) , pero eso no cambia el significado de return; .


No hay necesidad de aumentar explícitamente StopIteration ya que eso es lo que hace una declaración de return StopIteration para una función de generador, así que sí, son lo mismo. Pero no, solo usar return es más pitónico.

De: http://docs.python.org/2/reference/simple_stmts.html#the-return-statement (válido para Python 3.2)

En una función de generador, la declaración de retorno no tiene permitido incluir una lista_expresión. En ese contexto, un retorno simple indica que el generador está listo y causará que se genere StopIteration.

O como señala @Bakuriu, la semántica de los generadores ha cambiado ligeramente para Python 3.3, por lo que lo siguiente es más apropiado:

En una función de generador, la declaración de retorno indica que el generador está listo y causará que se genere StopIteration. El valor devuelto (si existe) se usa como un argumento para construir StopIteration y se convierte en el atributo StopIteration.value.