2011-03-03 6 views
9

Consideremos el siguiente código Python:¿Los argumentos de longitud variable de python (* args) expanden un generador en el tiempo de llamada a la función?

def f(*args): 
    for a in args: 
     pass 

foo = ['foo', 'bar', 'baz'] 

# Python generator expressions FTW 
gen = (f for f in foo) 

f(*gen) 

¿Se *args expande automáticamente el generador a llamadas en tiempo? Dicho de otra manera, ¿estoy iterando sobre gen dos veces dentro de f(*gen), una vez para expandir *args y una vez para iterar sobre args? ¿O se conserva el generador en condiciones prístinas, mientras que la iteración solo ocurre una vez durante el ciclo for?

Respuesta

13

El generador se expande en el momento de la llamada de función, como se puede comprobar fácilmente:

def f(*args): 
    print(args) 
foo = ['foo', 'bar', 'baz'] 
gen = (f for f in foo) 
f(*gen) 

imprimirá

('foo', 'bar', 'baz') 
+1

Sería bueno agregar al final del ejemplo que al llamar 'f (* gen)' por segunda vez se devuelve '()', para mostrar que al invocar 'f' se agota el generador para las líneas subsiguientes. – cjerdonek

2

¿Por qué no mirar y ver qué gen está en f()? Agregue print args como la primera línea. Si todavía es un objeto generador, te dirá. Esperaría que el argumento desempaquetado lo convirtiera en una tupla.

+1

Siempre que tenga 'f (* arg)', 'arg' sí será siempre una tupla en la función – NullUserException

1

Su realmente no necesita

gen = (f for f in foo) 

Llamando

f(*foo) 

es la salida

('foo', 'bar', 'baz') 
+2

Este es el generador más simple posible, con fines de demostración, un generador de "identidad", si se quiere. –

Cuestiones relacionadas