Args e Kwargs em Python: Guia Completo

Publicado em: 19/01/2026
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

    Fundamentos
    Foto do Leandro Hirt

    Entendendo o módulo collections em Python

    O módulo collections é uma das ferramentas mais poderosas e subutilizadas da biblioteca padrão do Python. Embora os tipos de

    Ler mais

    Tempo de leitura: 10 minutos
    17/02/2026
    Fundamentos
    Foto do Leandro Hirt

    Hash de senhas em Python: Crie hashes seguros em minutos

    Garantir a segurança dos dados dos usuários é uma das responsabilidades mais críticas de qualquer desenvolvedor de software. Quando falamos

    Ler mais

    Tempo de leitura: 10 minutos
    16/02/2026
    Fundamentos
    Foto do Leandro Hirt

    Como usar zip em Python: guia para iniciantes

    A função zip() é uma das ferramentas mais úteis e, ao mesmo tempo, subestimadas para quem está começando a aprender

    Ler mais

    Tempo de leitura: 9 minutos
    16/02/2026
    Fundamentos
    Foto do Leandro Hirt

    Como criar um cliente TCP simples em Python

    Criar um cliente TCP simples em Python é um dos primeiros passos fundamentais para quem deseja entender como a internet

    Ler mais

    Tempo de leitura: 10 minutos
    15/02/2026
    Fundamentos
    Foto do Leandro Hirt

    UnicodeDecodeError no Python: Como resolver de forma simples

    Se você está começando a programar ou já desenvolve projetos há algum tempo, certamente já se deparou com um erro

    Ler mais

    Tempo de leitura: 10 minutos
    15/02/2026
    Fundamentos
    Foto do Leandro Hirt

    Criando scripts executáveis em Python de Forma Fácil

    Transformar um roteiro de código em um aplicativo independente é um dos passos mais empolgantes na jornada de um programador.

    Ler mais

    Tempo de leitura: 8 minutos
    15/02/2026