Función de llamada de diferencia con parámetro de asterisco y sin

Sé cuál es el significado de un asterisco en una definición de función en Python.

Sin embargo, a menudo veo asteriscos para llamadas a funciones con parámetros como:

def foo(*args, **kwargs): first_func(args, kwargs) second_func(*args, **kwargs) 

¿Cuál es la diferencia entre la primera y la segunda función de llamada?

args = [1,2,3]

func(*args) == func(1,2,3) variables se desempaquetan fuera de lista (o cualquier otro tipo de secuencia) como parámetros

func(args) == func([1,2,3]) se pasa una lista

kwargs = dict(a=1,b=2,c=3)

func(kwargs) == func({'a':1, 'b':2, 'c':3}) se pasa un dict

func(**kwargs) == func(a=1,b=2,c=3) (clave, valor) se descomprimen fuera del dict (o cualquier otro tipo de mapeo) como parámetros nombrados

La diferencia es cómo los argumentos se pasan a las funciones llamadas. Cuando usa el * , los argumentos se descomprimen (si son una lista o una tupla); de lo contrario, simplemente se pasan tal como están.

Aquí hay un ejemplo de la diferencia:

 >>> def add(a, b): ... print a + b ... >>> add(*[2,3]) 5 >>> add([2,3]) Traceback (most recent call last): File "", line 1, in  TypeError: add() takes exactly 2 arguments (1 given) >>> add(4, 5) 9 

Cuando prefijo el argumento con * , en realidad desempaquetó la lista en dos argumentos separados, que se pasaron a add como a y b . Sin él, simplemente pasó a la lista como un solo argumento.

Lo mismo ocurre con los diccionarios y ** , excepto que se pasan como argumentos con nombre en lugar de argumentos ordenados.

 >>> def show_two_stars(first, second='second', third='third'): ... print "first: " + str(first) ... print "second: " + str(second) ... print "third: " + str(third) >>> show_two_stars('a', 'b', 'c') first: a second: b third: c >>> show_two_stars(**{'second': 'hey', 'first': 'you'}) first: you second: hey third: third >>> show_two_stars({'second': 'hey', 'first': 'you'}) first: {'second': 'hey', 'first': 'you'} second: second third: third 
 def fun1(*args): """ This function accepts a non keyworded variable length argument as a parameter. """ print args print len(args) >>> a = [] >>> fun1(a) ([],) 1 # This clearly shows that, the empty list itself is passed as a first argument. Since *args now contains one empty list as its first argument, so the length is 1 >>> fun1(*a) () 0 # Here the empty list is unwrapped (elements are brought out as separate variable length arguments) and passed to the function. Since there is no element inside, the length of *args is 0 >>>