Opcional rendimiento o retorno en python3. ¿Cómo?

Me gustaría tener una función que, opcionalmente, pueda devolver o producir el resultado. Aquí hay un ejemplo.

def f(option=True): ... for...: if option: yield result else: results.append(result) if not option: return results 

Por supuesto, esto no funciona, lo he intentado con python3 y siempre obtengo un generador sin importar el valor de opción que establezca. Por lo que he entendido, Python verifica el cuerpo de la función y, si existe un yield , el resultado será un generador. ¿Hay alguna manera de evitar esto y hacer una función que pueda regresar o rendir a voluntad?

Usted no puede Cualquier uso del yield hace de la función un generador.

Podría envolver su función con una que use list() para almacenar todos los valores que el generador produce en un objeto de lista y devuelve eso:

 def f_wrapper(option=True): gen = f() if option: return gen # return the generator unchanged return list(gen) # return all values of the generator as a list 

Sin embargo, en términos generales, este es un mal diseño . No hagas que tus funciones alteren el comportamiento de esta manera; manténgase en un tipo de retorno (un generador o un objeto) y no permita que cambie entre los dos.

Considere dividir esto en dos funciones en su lugar:

 def f(): yield result def f_as_list(): return list(f()) 

y use f() si necesita el generador, y f_as_list() si quiere tener una lista en su lugar.

Dado que list() , (y next() para acceder solo a un valor de un generador) son funciones integradas, rara vez necesita usar un contenedor. Simplemente llama a esas funciones directamente:

 # access elements one by one gen = f() one_value = next(gen) # convert the generator to a list all_values = list(f()) 

Que hay de esto

 def make_f_or_generator(option): def f(): return "I am a function." def g(): yield "I am a generator." if option: return f else: return g 

Esto le da al menos la opción de crear una función o un generador.