Tengo un generador de generator y también un método de conveniencia para generate_all .
def generator(some_list): for i in some_list: yield do_something(i) def generate_all(): some_list = get_the_list() return generator(some_list) # <-- Is this supposed to be return or yield? ¿Debería generate_all return o yield ? Quiero que los usuarios de ambos métodos lo usen de la misma manera, es decir
for x in generate_all()debe ser igual a
some_list = get_the_list() for x in generate(some_list)Probablemente estés buscando Delegación de Generador (PEP380)
Para iteradores simples,
yield from iterablees esencialmente solo una forma abreviada defor item in iterable: yield item
def generator(iterable): for i in iterable: yield do_something(i) def generate_all(): yield from generator(get_the_list())Es bastante conciso y también tiene una serie de otras ventajas, como poder encadenar iterables arbitrarios/diferentes.
return generator(list) hace lo que quieres. Pero ten en cuenta que
yield from generator(list) sería equivalente, pero con la oportunidad de generar más valores después de que se agote el generator . Por ejemplo:
def generator_all_and_then_some(): list = get_the_list() yield from generator(list) yield "one last thing"Las siguientes dos declaraciones parecerán ser funcionalmente equivalentes en este caso particular:
return generator(list)y
yield from generator(list)El último es aproximadamente el mismo que
for i in generator(list): yield i La declaración de return devuelve el generador que está buscando. Una instrucción yield from o yield convierte toda su función en algo que devuelve un generador, que pasa por el que está buscando.
Desde el punto de vista del usuario, no hay diferencia. Sin embargo, internamente, el return es posiblemente más eficiente ya que no envuelve generator(list) en un generador de paso superfluo. Si planea realizar algún procesamiento en los elementos del generador envuelto, use alguna forma de yield , por supuesto.
Lo return .
yield ing* haría que generate_all() se evaluara como un generador en sí mismo, y llamar a next a ese generador externo devolvería el generador interno devuelto por la primera función, que no es lo que querrías.
* Sin incluir yield from