Args e Kwargs em Python: Guia Completo

Tempo de leitura: 11 minutos
Logotipo do Python em tamanho grande centralizado acima do texto 'Args e Kwargs', em um design minimalista com fundo colorido sólido

Você já se deparou com funções que aceitam um número variável de argumentos? Ou já viu aqueles estranhos *args e **kwargs em códigos Python e ficou confuso sobre o que eles fazem? Se a resposta for sim, este guia vai esclarecer tudo de forma simples e prática.

Os *args e **kwargs são ferramentas poderosas que tornam suas funções em Python muito mais flexíveis. Eles permitem que você passe quantos argumentos quiser, sem precisar definir cada um separadamente.

O Que São Args e Kwargs

Antes de explicar *args e **kwargs, é importante entender que esses nomes são apenas convenções. O que realmente importa são os asteriscos (* e **).

Você poderia usar *numeros ou **opcoes, por exemplo. Mas a comunidade Python usa args (de “arguments”) e kwargs (de “keyword arguments”) como padrão, seguindo as convenções da PEP 8.

  • *args permite passar um número variável de argumentos posicionais
  • **kwargs permite passar um número variável de argumentos nomeados (chave-valor)

Esses recursos tornam suas funções extremamente versáteis, especialmente quando você não sabe de antemão quantos parâmetros serão necessários.

Como Funciona o *args

O *args coleta todos os argumentos posicionais extras em uma tupla. Veja um exemplo prático:

Python
def somar(*args):
    total = 0
    for numero in args:
        total += numero
    return total

# Chamando com diferentes quantidades de argumentos
print(somar(1, 2, 3))           # 6
print(somar(10, 20, 30, 40))    # 100
print(somar(5))                 # 5

Perceba que a função aceita qualquer quantidade de números. Internamente, o Python transforma todos esses argumentos em uma tupla, permitindo que você itere sobre eles.

O nome args dentro da função se comporta como uma tupla normal. Você pode usar índices, fatiar, ou percorrê-la com laços for.

Exemplos Práticos com *args

Vamos ver alguns casos de uso reais para entender melhor quando usar *args:

Python
def maior_numero(*args):
    """Retorna o maior número entre os argumentos"""
    if not args:
        return None
    return max(args)

def concatenar_textos(*args):
    """Junta todos os textos passados"""
    return " ".join(args)

def criar_lista_compras(*args):
    """Cria uma lista formatada de compras"""
    print("Lista de Compras:")
    for i, item in enumerate(args, 1):
        print(f"{i}. {item}")

# Testando
print(maior_numero(5, 12, 3, 89, 45))  # 89
print(concatenar_textos("Python", "é", "incrível"))  # Python é incrível
criar_lista_compras("Arroz", "Feijão", "Macarrão")

Esses exemplos mostram como *args torna o código mais limpo e reutilizável. Você não precisa criar múltiplas versões da mesma função para diferentes quantidades de parâmetros.

Como Funciona o **kwargs

Enquanto *args trabalha com argumentos posicionais, o **kwargs lida com argumentos nomeados. Ele os coleta em um dicionário.

Python
def exibir_informacoes(**kwargs):
    for chave, valor in kwargs.items():
        print(f"{chave}: {valor}")

# Chamando com diferentes argumentos nomeados
exibir_informacoes(nome="João", idade=25, cidade="São Paulo")
# Saída:
# nome: João
# idade: 25
# cidade: São Paulo

exibir_informacoes(produto="Notebook", preco=2500, marca="Dell")

O **kwargs é perfeito quando você quer aceitar opções configuráveis sem saber exatamente quais serão passadas. É muito usado em bibliotecas Python para fornecer flexibilidade.

Combinando Parâmetros Normais com *args

Você pode misturar parâmetros regulares com *args. Mas existe uma regra importante: os parâmetros normais devem vir antes do *args.

Python
def calcular_media(nome, *notas):
    """Calcula a média das notas de um aluno"""
    if not notas:
        return f"{nome} não tem notas cadastradas"
    
    media = sum(notas) / len(notas)
    return f"{nome} teve média {media:.2f}"

print(calcular_media("Maria", 8, 7.5, 9, 8.5))  # Maria teve média 8.25
print(calcular_media("João", 10, 9))            # João teve média 9.50
print(calcular_media("Pedro"))                   # Pedro não tem notas cadastradas

Neste exemplo, nome é obrigatório, mas você pode passar quantas notas quiser depois dele. Isso oferece um equilíbrio perfeito entre flexibilidade e estrutura.

Combinando Parâmetros Normais com **kwargs

Da mesma forma, você pode combinar parâmetros regulares com **kwargs:

Python
def criar_perfil(nome, idade, **informacoes_extra):
    """Cria um perfil de usuário com informações básicas e opcionais"""
    perfil = {
        "nome": nome,
        "idade": idade
    }
    
    # Adiciona as informações extras
    perfil.update(informacoes_extra)
    
    return perfil

# Usando a função
usuario1 = criar_perfil("Ana", 28, cidade="Rio de Janeiro", profissao="Designer")
usuario2 = criar_perfil("Carlos", 35, estado="SP", hobby="Fotografia", pets=2)

print(usuario1)
print(usuario2)

Esse padrão é muito comum em frameworks web como Flask e Django, onde funções aceitam configurações opcionais.

Usando *args e **kwargs Juntos

Você pode usar *args e **kwargs na mesma função. A ordem é crucial:

  1. Parâmetros normais
  2. *args
  3. **kwargs
Python
def fazer_pedido(cliente, *itens, **opcoes):
    """Registra um pedido com itens e opções de entrega"""
    print(f"Cliente: {cliente}")
    print(f"Itens do pedido: {', '.join(itens)}")
    
    if opcoes:
        print("Opções de entrega:")
        for chave, valor in opcoes.items():
            print(f"  {chave}: {valor}")

fazer_pedido(
    "Maria Silva",
    "Pizza", "Refrigerante", "Sobremesa",
    endereco="Rua A, 123",
    forma_pagamento="Cartão",
    entrega_rapida=True
)

Essa flexibilidade total permite criar APIs muito expressivas. É um padrão comum em programação orientada a objetos no Python.

Desempacotando com * e **

Os asteriscos também funcionam ao contrário: você pode desempacotar listas e dicionários ao chamar funções.

Python
def calcular(a, b, c):
    return a + b + c

# Desempacotando uma lista
numeros = [10, 20, 30]
resultado = calcular(*numeros)  # Equivale a calcular(10, 20, 30)
print(resultado)  # 60

# Desempacotando um dicionário
def apresentar(nome, idade, cidade):
    print(f"{nome} tem {idade} anos e mora em {cidade}")

dados = {"nome": "Pedro", "idade": 30, "cidade": "Brasília"}
apresentar(**dados)  # Equivale a apresentar(nome="Pedro", idade=30, cidade="Brasília")

Esse recurso é muito útil quando você trabalha com listas ou dicionários que já contêm os dados necessários.

Diferenças Entre *args e **kwargs

Vamos consolidar as diferenças principais em uma tabela comparativa:

Característica*args**kwargs
Tipo de dadosTuplaDicionário
Tipo de argumentosPosicionaisNomeados (chave=valor)
Sintaxe na chamadafunc(1, 2, 3)func(a=1, b=2)
Acesso aos valoresPor índice ou loopPor chave ou .items()
Ordem importa?SimNão
Uso comumListas de valoresConfigurações opcionais

Entender essas diferenças ajuda você a escolher qual usar em cada situação. Muitas vezes, você usará ambos para máxima flexibilidade.

Casos de Uso Reais

Agora vamos ver exemplos práticos que você encontrará em projetos reais:

Python
# 1. Logging personalizado
def log_mensagem(nivel, *mensagens, **contexto):
    """Sistema de log flexível"""
    texto_completo = " ".join(str(m) for m in mensagens)
    print(f"[{nivel}] {texto_completo}")
    
    if contexto:
        print("  Contexto:", contexto)

log_mensagem("INFO", "Usuário", "fez", "login", usuario="joao", ip="192.168.1.1")

# 2. Criar consultas SQL dinâmicas (exemplo simplificado)
def criar_filtros(**condicoes):
    """Gera cláusula WHERE baseada em condições"""
    if not condicoes:
        return ""
    
    filtros = [f"{campo} = '{valor}'" for campo, valor in condicoes.items()]
    return "WHERE " + " AND ".join(filtros)

print(criar_filtros(idade=25, cidade="São Paulo", ativo=True))

# 3. Wrapper de funções (decorators usam muito isso)
def medir_tempo(func):
    """Exemplo simplificado de decorator"""
    def wrapper(*args, **kwargs):
        print(f"Executando {func.__name__}...")
        resultado = func(*args, **kwargs)
        print("Concluído!")
        return resultado
    return wrapper

@medir_tempo
def processar_dados(arquivo, verbose=False):
    print(f"Processando {arquivo}, verbose={verbose}")

processar_dados("dados.csv", verbose=True)

Esses padrões aparecem frequentemente em códigos profissionais, especialmente em APIs e bibliotecas de terceiros. Saber usar *args e **kwargs é essencial para ler e escrever código Python avançado.

Erros Comuns ao Usar Args e Kwargs

Mesmo programadores experientes cometem alguns erros ao trabalhar com *args e **kwargs. Aqui estão os mais comuns:

1. Ordem incorreta dos parâmetros:

Python
# ERRADO - kwargs antes de args
def funcao_errada(**kwargs, *args):  # SyntaxError!
    pass

# CERTO
def funcao_certa(*args, **kwargs):
    pass

2. Tentar modificar args (que é uma tupla):

Python
def tentar_modificar(*args):
    args[0] = 100  # TypeError: tuple object does not support item assignment
    
# Se precisar modificar, converta para lista
def modificar_correto(*args):
    lista_args = list(args)
    lista_args[0] = 100
    return lista_args

3. Esquecer de desempacotar ao passar listas/dicionários:

Python
def somar(a, b, c):
    return a + b + c

numeros = [1, 2, 3]

# ERRADO
resultado = somar(numeros)  # TypeError: missing 2 required arguments

# CERTO
resultado = somar(*numeros)

Evitar esses erros economiza muito tempo de depuração. Se você está começando, consulte o guia sobre erros comuns em Python para mais dicas.

Boas Práticas com Args e Kwargs

Para usar *args e **kwargs de forma profissional, siga estas recomendações:

  • Use nomes descritivos quando possível: Se você sabe que vai receber números, use *numeros em vez de *args
  • Documente bem suas funções: Explique que tipos de argumentos são esperados nas docstrings
  • Não abuse: Se sua função sempre precisa dos mesmos 3 parâmetros, defina-os explicitamente
  • Valide os dados recebidos: Verifique se os argumentos fazem sentido antes de processá-los
  • Combine com valores padrão: Você pode ter parâmetros com valores padrão antes do *args
Python
def funcao_bem_documentada(obrigatorio, opcional="padrao", *args, **kwargs):
    """
    Exemplo de função bem documentada.
    
    Args:
        obrigatorio: Parâmetro que sempre deve ser fornecido
        opcional: Parâmetro com valor padrão (default: "padrao")
        *args: Argumentos adicionais posicionais
        **kwargs: Argumentos adicionais nomeados
        
    Returns:
        Dicionário com informações processadas
    """
    return {
        "obrigatorio": obrigatorio,
        "opcional": opcional,
        "extras_posicionais": args,
        "extras_nomeados": kwargs
    }

print(funcao_bem_documentada("teste", 1, 2, 3, chave="valor"))

Seguir essas práticas torna seu código mais legível e fácil de manter. Para mais orientações, consulte a documentação oficial sobre funções.

Perguntas Frequentes (FAQ)

1. Qual a diferença entre *args e **kwargs?

O *args captura argumentos posicionais em uma tupla, enquanto **kwargs captura argumentos nomeados em um dicionário.

2. Posso usar outros nomes além de args e kwargs?

Sim! O importante são os asteriscos (* e **). Você pode usar *numeros ou **opcoes, mas args e kwargs são convenção.

3. Em que ordem devo colocar os parâmetros?

A ordem é: parâmetros normais, *args, parâmetros com valor padrão, **kwargs.

4. Posso modificar os valores dentro de args?

Não diretamente, pois args é uma tupla (imutável). Converta para lista primeiro se precisar modificar.

5. Como acesso valores específicos em kwargs?

Use a sintaxe de dicionário: kwargs[‘chave’] ou kwargs.get(‘chave’, valor_padrao).

6. Posso usar *args em funções lambda?

Sim! Exemplo: lambda *args: sum(args) cria uma função que soma todos os argumentos passados.

7. O que acontece se eu não passar argumentos para uma função com *args?

A função funciona normalmente. O args será uma tupla vazia ().

8. Posso combinar *args com list comprehension?

Sim! Exemplo: def dobrar(*args): return [x * 2 for x in args].

9. Como desempacoto uma lista ao chamar uma função?

Use o asterisco: se você tem lista = [1, 2, 3], chame funcao(*lista) para desempacotar.

10. Quando devo usar **kwargs em vez de parâmetros normais?

Use **kwargs quando não souber quais argumentos opcionais o usuário pode querer passar, como em configurações flexíveis.

11. Args e kwargs deixam o código mais lento?

O impacto na performance é mínimo. A flexibilidade que oferecem geralmente vale muito mais que qualquer pequena perda de velocidade.

12. Posso usar type hints com *args e **kwargs?

Sim! Exemplo: def funcao(*args: int, **kwargs: str) indica que args contém inteiros e kwargs contém strings.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Ilustração minimalista do logotipo da linguagem de programação Python ao lado do texto REGEX em fundo neutro
    Fundamentos
    Foto do Leandro Hirt

    Regex Python: Tudo Sobre Expressões Regulares

    Se você já tentou encontrar padrões específicos em textos, validar formatos de email ou extrair informações de documentos, provavelmente já

    Ler mais

    Tempo de leitura: 12 minutos
    05/01/2026
    Logo do Python, texto TXT e ícone de bloco de notas representando arquivos de texto
    Fundamentos
    Foto do Leandro Hirt

    Como Ler Arquivos TXT no Python

    Trabalhar com arquivos de texto é uma das tarefas mais comuns na programação. Aprender como ler arquivo TXT no Python

    Ler mais

    Tempo de leitura: 14 minutos
    24/12/2025
    Comparação visual entre Python 2 e Python 3 com ícones minimalistas
    Fundamentos
    Foto do Leandro Hirt

    Python 2 vs Python 3: Principais Diferenças

    Se você está começando a estudar Python ou já trabalha com a linguagem, provavelmente já se deparou com uma dúvida

    Ler mais

    Tempo de leitura: 20 minutos
    22/12/2025
    Pessoa pensando com um monitor desfocado ao fundo
    Fundamentos
    Foto do Leandro Hirt

    Tipos de Dados em Python: int, float, str, list e dict

    Aprenda tudo sobre os principais tipos de dados em Python: int, float, str, list e dict. Guia completo com exemplos

    Ler mais

    Tempo de leitura: 14 minutos
    21/12/2025
    Pessoa usando tablet com caneta digital para planejar tarefas em checklist, representando organização, planejamento e produtividade digital.
    Fundamentos
    Foto do Leandro Hirt

    Como Ordenar Listas no Python (Sort vs Sorted)

    Você já ficou confuso sobre quando usar sort() ou sorted() para organizar suas listas em Python? Não está sozinho. Esses

    Ler mais

    Tempo de leitura: 12 minutos
    20/12/2025
    Logo do Python com uma faca, simbolizando fatiamento
    Fundamentos
    Foto do Leandro Hirt

    Fatiamento em Python: Tudo Sobre Slicing

    O fatiamento (ou slicing) é uma técnica fundamental em Python que permite extrair partes específicas de sequências como listas, strings

    Ler mais

    Tempo de leitura: 11 minutos
    13/12/2025