`*args` e `**kwargs` — Argumentos Flexíveis em Funções
À medida que um código Python cresce, funções frequentemente precisam lidar com entradas variadas.
É aí que entram *args e **kwargs — eles permitem aceitar um número arbitrário de argumentos sem alterar constantemente a assinatura da função.
Quando usados com intenção, tornam APIs mais flexíveis e fáceis de evoluir.
Entendendo o *args
*args reúne argumentos posicionais extras em uma tupla.
def log_values(*args):
for value in args:
print(value)
log_values(1, 2, 3)
É útil quando:
- o número de entradas não é fixo
- a ordem importa
- você quer uma interface simples
Entendendo o **kwargs
**kwargs reúne argumentos nomeados extras em um dicionário.
def log_config(**kwargs):
for key, value in kwargs.items():
print(key, value)
log_config(debug=True, retries=3)
Esse padrão é comum em:
- configurações
- wrappers e decorators
- APIs extensíveis
Usando *args e **kwargs juntos
def handler(*args, **kwargs):
print("args:", args)
print("kwargs:", kwargs)
handler(1, 2, debug=True)
Aparece bastante em bibliotecas que precisam de flexibilidade máxima.
Encaminhando argumentos
Um uso muito prático é o repasse de argumentos:
def wrapper(*args, **kwargs):
return target_function(*args, **kwargs)
Isso permite estender comportamentos sem alterar a interface original.
Um erro comum a evitar
Evite usar *args e **kwargs quando a função tem um contrato bem definido.
# API difícil de entender
def process(*args, **kwargs):
...
Se os parâmetros são conhecidos, declarar explicitamente costuma ser melhor.
Conclusão
Na minha experiência, *args e **kwargs funcionam melhor quando a flexibilidade é realmente necessária.
Usados com moderação, ajudam a criar APIs limpas e extensíveis.
Em excesso, escondem intenção e dificultam a manutenção.