Diga aí, o que o código abaixo irá produzir?
def func(a, b, c, d):
return (a + b) / (c + d)
lista_de_argumentos = [4, 6, 2, 3]
print func(*lista_de_argumentos)
Se você sabe a resposta (que é 2), provavelmente já conhece esse uso do * (asterisco ou estrela).
Caso não tenha entendido muito bem, leia o resto do texto.
A estrela (asterisco) na chamada de funções
A função func listada acima deve receber 4 parâmetros (a, b, c e d). Quando passamos um argumento precedido de um asterisco, esse argumento (se for uma lista ou tupla) será desempacotado e cada um dos elementos será passado como um dos argumentos posicionais da função. No exemplo acima, o primeiro elemento de lista_de_argumentos será passado ao argumento a, o segundo ao elemento b, e assim por diante. No exemplo acima, a chamada de função func(*lista_de_argumentos) dá no mesmo que func(4, 6, 2, 3), pois o desempacotamento é automático. A imagem abaixo ilustra o que acontece:
Se lista_de_argumentos tivesse uma quantidade de elementos diferente da quantidade de argumentos exigidos por func, uma exceção seria disparada. Veja:
>>> lista = [4, 6, 2, 3, 10] >>> print func(*lista) ------------------------------------------------------------------ TypeError Traceback (most recent call last) in () ----> 1 print func(*lista) TypeError: func() takes exactly 4 arguments (5 given)
A estrela-dupla na chamada de funções
De forma semelhante, podemos também desempacotar dicionários em chamadas de funções. Nesses dicionários, as chaves deverão ser os nomes dos argumentos e os valores serão os valores que queremos passar como argumentos. Seguindo com o exemplo da função func, poderíamos passar um dicionário com os nossos parâmetros nomeados, precedido de **:
>>> argumentos = {'d': 3, 'c': 2, 'b': 6, 'a': 4}
>>> print func(**argumentos)
2
Assim, os valores armazenados no dicionário serão desempacotados direitinho como argumentos para a função, de acordo com as chaves correspondentes a eles. Assim, 4 será o argumento a, 6 será passado como argumento para b e assim por diante.
Quando usar isso?
Esse açúcar sintático oferecido por Python é bem útil quando temos uma lista contendo os valores que deverão ser passados para uma função. Por exemplo, ao invés de fazer:
>>> lista = [6, 4, 2, 3] >>> func(lista[0], lista[1], lista[2], lista[3])
podemos fazer:
>>> lista = [6, 4, 2, 3] >>> func(*lista)
O uso vai surgir da necessidade. Às vezes temos uma função que retorna uma tupla de n valores e queremos passar esses valores diretamente como argumentos para outra função, que exige n parâmetros. É aí que entra o *.
