Menu

*args e **kwargs em Python: argumentos posicionais e por palavra-chave flexíveis

O que *args e **kwargs significam, quando usar e como encaminhar argumentos de forma limpa entre funções.

Quando você não sabe quantos argumentos serão

A maioria das funções recebe um número fixo de parâmetros. Mas às vezes você precisa de algo mais flexível — um logger que aceita qualquer número de mensagens, uma função wrapper que encaminha tudo que recebeu para outra função, uma função de plotagem que aceita configuração sem saber exatamente quais opções quem chama vai usar.

O Python resolve isso com dois marcadores especiais na lista de parâmetros: *args e **kwargs.

*args coleta argumentos posicionais

Um asterisco simples diz "empacote qualquer argumento posicional extra numa tupla":

main.py
Output
Click Run to see the output here.

Dentro da função, args é uma tupla normal. Você pode fazer laço, indexar, passar para len() ou fatiar.

*args geralmente aparece junto com parâmetros nomeados:

main.py
Output
Click Run to see the output here.

first pega o primeiro argumento; *rest empacota tudo depois numa tupla.

**kwargs coleta argumentos por palavra-chave

Dois asteriscos fazem o equivalente para argumentos por palavra-chave, empacotando num dict:

main.py
Output
Click Run to see the output here.

Dentro de describe, kwargs é um dict normal. As chaves são os nomes dos argumentos como strings.

Usando os dois juntos

Você pode usar os dois na mesma função. A convenção é *args antes de **kwargs:

main.py
Output
Click Run to see the output here.

A ordem completa dos parâmetros, da esquerda para a direita, é:

  1. Parâmetros posicionais normais (obrigatórios ou com defaults).
  2. *args.
  3. Parâmetros só por palavra-chave (qualquer coisa depois de *args precisa ser passada por palavra-chave).
  4. **kwargs.
main.py
Output
Click Run to see the output here.

title pega o primeiro posicional. O resto dos posicionais vai para tags. draft precisa ser passado por palavra-chave (veio depois de *tags). Quaisquer outros argumentos por palavra-chave caem em metadata.

Desempacotando com * e ** no ponto de chamada

Os asteriscos também funcionam ao contrário — espalhando uma sequência ou dict nos argumentos de uma chamada:

main.py
Output
Click Run to see the output here.

Isso é incrivelmente útil para encaminhar argumentos:

main.py
Output
Click Run to see the output here.

wrapped não precisa saber quais argumentos log espera. Só coleta tudo e encaminha. Esse padrão aparece constantemente em decoradores (tópico mais avançado) e funções wrapper.

Quando *args e **kwargs são a escolha errada

É fácil empolgar e usar em todo lugar. Dois avisos:

Eles escondem o que uma função espera

Se cada função do seu código é def f(*args, **kwargs), o código que chama não faz ideia de quais argumentos são válidos. Use parâmetros nomeados sempre que puder, e deixe *args/**kwargs carregarem só entradas genuinamente variáveis ou encaminhamento puro.

Mensagens de erro ficam vagas

Um nome de palavra-chave com typo vira um None silencioso ou um KeyError lá no fundo da função, em vez de um "unexpected keyword argument" imediato no ponto de chamada. Parâmetros nomeados te dão feedback muito melhor.

Como regra: prefira parâmetros nomeados por padrão, e recorra a *args/**kwargs só quando a função é genuinamente flexível ou está encaminhando argumentos para outra função.

Um exemplo prático pequeno

Uma helper estilo plotagem que envolve uma função de terceiros com alguns defaults:

main.py
Output
Click Run to see the output here.

O *values deixa quem chama passar qualquer número de itens; **style engole configuração extra sem exigir que toda opção seja um parâmetro nomeado. É flexível sem ser opaco, porque a lógica interna te diz exatamente quais chaves lê de style.

Revisão

  • *args empacota argumentos posicionais extras numa tupla.
  • **kwargs empacota argumentos por palavra-chave extras num dict.
  • No ponto de chamada, *seq e **dict desempacotam na direção oposta.
  • Parâmetros precisam aparecer na ordem: normal → *args → só palavra-chave → **kwargs.
  • Não exagere — parâmetros nomeados são mais claros quando dá para usar.

A seguir: lambda, uma forma de escrever funções pequenas e descartáveis inline.

Perguntas frequentes

O que é *args em Python?

*args coleta qualquer argumento posicional extra numa tupla. def f(*args): permite chamar f(1, 2, 3) e receber args como (1, 2, 3). O nome args é convenção — você poderia chamar de qualquer coisa, mas *args é o que todo mundo usa.

O que é **kwargs em Python?

**kwargs coleta qualquer argumento por palavra-chave extra num dict. def f(**kwargs): permite chamar f(name='Ada', age=30) e receber kwargs como {'name': 'Ada', 'age': 30}. Juntos, *args e **kwargs deixam uma função aceitar qualquer combinação de argumentos.

Preciso chamar de args e kwargs?

Não, os asteriscos é que importam, não os nomes. *values e **options funcionam identicamente. Mas args e kwargs são convenção quase universal em código Python — fique com elas a menos que tenha razão específica para escolher algo mais descritivo.

Aprenda a programar com o Coddy

COMEÇAR