Parâmetros: posicionais, nomeados e valores padrão
1. Introdução aos Parâmetros em Python
Em Python, a distinção entre parâmetros e argumentos é fundamental: parâmetros são as variáveis listadas na definição da função, enquanto argumentos são os valores reais passados durante a chamada. Essa flexibilidade na definição de parâmetros é uma das características mais poderosas da linguagem, permitindo criar funções que se adaptam a diferentes contextos de uso.
Python oferece três mecanismos principais para definição de parâmetros:
- Posicionais: ordem obrigatória de passagem
- Nomeados (keyword arguments): identificados por chave=valor
- Valores padrão: argumentos opcionais com valores predefinidos
Dominar esses conceitos é essencial para escrever código limpo, legível e flexível.
2. Parâmetros Posicionais
Parâmetros posicionais são a forma mais básica de definir uma função. A ordem dos argumentos na chamada deve corresponder exatamente à ordem dos parâmetros na definição.
def calcular_media(a, b, c):
return (a + b + c) / 3
# Uso correto
print(calcular_media(10, 20, 30)) # Saída: 20.0
# Erro comum - ordem incorreta
print(calcular_media(30, 10, 20)) # Saída: 20.0 (funciona, mas semântica errada)
Características importantes:
- Número exato de argumentos é obrigatório
- A ordem importa semanticamente
- Se você inverter a ordem, o código executa, mas o resultado pode ser logicamente incorreto
def exibir_dados(nome, idade, cidade):
return f"{nome} tem {idade} anos e mora em {cidade}"
print(exibir_dados("Ana", 28, "São Paulo"))
# Saída: Ana tem 28 anos e mora em São Paulo
3. Parâmetros Nomeados (Keyword Arguments)
Parâmetros nomeados permitem especificar argumentos usando a sintaxe chave=valor, tornando o código mais legível e flexível quanto à ordem.
def criar_perfil(usuario, email, idade, pais):
return f"Perfil: {usuario}, Email: {email}, Idade: {idade}, País: {pais}"
# Vantagem: ordem não importa
print(criar_perfil(
idade=30,
usuario="joao123",
pais="Brasil",
email="joao@email.com"
))
# Saída: Perfil: joao123, Email: joao@email.com, Idade: 30, País: Brasil
Combinação com posicionais: parâmetros posicionais devem vir antes dos nomeados.
def conectar(host, porta, protocolo="http"):
return f"{protocolo}://{host}:{porta}"
# Válido
print(conectar("localhost", 8080, protocolo="https"))
# Inválido - SyntaxError
# print(conectar(host="localhost", 8080))
4. Valores Padrão (Default Parameters)
Valores padrão tornam parâmetros opcionais, simplificando chamadas comuns.
def saudacao(nome, saudacao="Olá"):
return f"{saudacao}, {nome}!"
print(saudacao("Maria")) # Saída: Olá, Maria!
print(saudacao("João", "Oi")) # Saída: Oi, João!
⚠️ Armadilha comum: valores padrão mutáveis são avaliados apenas uma vez, no momento da definição da função.
def adicionar_item(item, lista=[]): # PROBLEMA!
lista.append(item)
return lista
print(adicionar_item("maçã")) # ['maçã']
print(adicionar_item("banana")) # ['maçã', 'banana'] - ERRO!
Solução correta:
def adicionar_item(item, lista=None):
if lista is None:
lista = []
lista.append(item)
return lista
print(adicionar_item("maçã")) # ['maçã']
print(adicionar_item("banana")) # ['banana']
5. Regras de Combinação e Ordenação
Python 3.8+ introduziu sintaxes especiais para controle fino de parâmetros.
Parâmetros exclusivamente posicionais (sintaxe /):
def dividir(a, b, /):
return a / b
# OK
print(dividir(10, 3))
# ERRO - TypeError
# print(dividir(a=10, b=3))
Parâmetros exclusivamente nomeados (sintaxe *):
def configurar(*, host, porta, debug=False):
return f"Host: {host}, Porta: {porta}, Debug: {debug}"
# OK
print(configurar(host="localhost", porta=8080))
# ERRO - TypeError
# print(configurar("localhost", 8080))
Combinação completa:
def processar_dados(a, b, /, c, d, *, e, f):
# a, b: exclusivamente posicionais
# c, d: posicionais ou nomeados
# e, f: exclusivamente nomeados
return a + b + c + d + e + f
print(processar_dados(1, 2, 3, d=4, e=5, f=6)) # OK
6. Boas Práticas e Casos Especiais
Documentação com docstrings:
def calcular_juros(valor, taxa=0.1, meses=12):
"""
Calcula juros compostos sobre um valor.
Args:
valor (float): Valor principal
taxa (float): Taxa de juros mensal (padrão 10%)
meses (int): Período em meses (padrão 12)
Returns:
float: Valor total com juros
"""
return valor * (1 + taxa) ** meses
Uso de Optional para tipagem:
from typing import Optional
def buscar_usuario(user_id: int, cache: Optional[bool] = None) -> str:
if cache is None:
cache = True # Valor padrão condicional
return f"Buscando usuário {user_id} (cache={cache})"
7. Exemplos Práticos e Erros Comuns
Função de cadastro com parâmetros mistos:
def cadastrar_usuario(nome, email, /, idade=None, *, admin=False):
"""
Cadastra um novo usuário no sistema.
Args:
nome (str): Nome do usuário (posicional obrigatório)
email (str): Email do usuário (posicional obrigatório)
idade (int, optional): Idade do usuário
admin (bool): Se é administrador (nomeado obrigatório)
"""
usuario = {
"nome": nome,
"email": email,
"idade": idade,
"admin": admin
}
return usuario
# Uso correto
print(cadastrar_usuario("Ana", "ana@email.com", idade=25, admin=False))
print(cadastrar_usuario("João", "joao@email.com", admin=True))
Erros comuns:
# TypeError: argumentos faltantes
# cadastrar_usuario("Ana") # Falta email
# TypeError: argumentos extras
# cadastrar_usuario("Ana", "ana@email.com", x=10) # x não é parâmetro
# SyntaxError: ordem incorreta
# cadastrar_usuario(admin=True, "Ana", "ana@email.com") # nomeados antes de posicionais
Referências
- Documentação Oficial: Definindo Funções — Seção completa sobre definição de funções, incluindo parâmetros padrão e keyword arguments
- PEP 570 – Python Positional-Only Parameters — Especificação oficial sobre parâmetros exclusivamente posicionais com sintaxe
/ - Real Python: Defining Python Functions With Optional Arguments — Tutorial prático sobre argumentos opcionais, valores padrão e armadilhas com mutabilidade
- Python Tips: Keyword Arguments — Guia conciso sobre argumentos nomeados e suas vantagens
- GeeksforGeeks: Default Arguments in Python — Explicação detalhada sobre valores padrão, incluindo o problema de objetos mutáveis
- Stack Overflow: "Least Astonishment" and the Mutable Default Argument — Discussão clássica sobre a armadilha de valores padrão mutáveis em Python