Funções: definindo, chamando e retornando valores
Funções são blocos de código reutilizáveis que executam uma tarefa específica. Em Python, elas são fundamentais para organizar, modularizar e dar clareza ao código. Este artigo aborda desde a definição básica até conceitos avançados, com exemplos práticos.
1. Definindo Funções em Python
A sintaxe para definir uma função em Python utiliza a palavra-chave def, seguida do nome da função, parênteses e dois pontos. O corpo da função deve ser indentado (geralmente com 4 espaços).
def saudacao():
"""Exibe uma mensagem de saudação."""
print("Olá, mundo!")
A docstring (entre """ """) é opcional, mas altamente recomendada. Ela documenta o propósito da função e pode ser acessada com help(nome_da_funcao) ou nome_da_funcao.__doc__.
def calcular_media(nota1, nota2):
"""
Calcula a média aritmética de duas notas.
Args:
nota1 (float): Primeira nota.
nota2 (float): Segunda nota.
Returns:
float: Média das notas.
"""
return (nota1 + nota2) / 2
2. Chamando Funções
Para executar uma função, basta usar seu nome seguido de parênteses. Se a função espera argumentos, eles devem ser fornecidos.
# Chamada simples
saudacao() # Saída: Olá, mundo!
# Chamada com argumentos
media = calcular_media(7.5, 8.2)
print(media) # Saída: 7.85
A ordem de execução segue a pilha de chamadas (call stack). Quando uma função é chamada, ela é empilhada; ao finalizar, é desempilhada e o controle retorna ao ponto de chamada.
def funcao_a():
print("Entrando em A")
funcao_b()
print("Saindo de A")
def funcao_b():
print("Entrando em B")
print("Saindo de B")
funcao_a()
# Saída:
# Entrando em A
# Entrando em B
# Saindo de B
# Saindo de A
3. Parâmetros e Argumentos
Parâmetros obrigatórios (posicionais)
São aqueles que devem ser fornecidos na ordem correta durante a chamada.
def exibir_dados(nome, idade, cidade):
print(f"{nome} tem {idade} anos e mora em {cidade}.")
exibir_dados("Ana", 28, "São Paulo")
Parâmetros com valores padrão
Valores padrão tornam o parâmetro opcional. Eles são avaliados apenas uma vez, no momento da definição.
def cadastro(nome, email, ativo=True):
if ativo:
print(f"{nome} ({email}) - Ativo")
else:
print(f"{nome} ({email}) - Inativo")
cadastro("João", "joao@email.com")
cadastro("Maria", "maria@email.com", False)
Passagem por posição vs. por nome
Argumentos podem ser passados por posição (na ordem dos parâmetros) ou por nome (usando o nome do parâmetro).
def configurar(tema, idioma, notificacoes=True):
print(f"Tema: {tema}, Idioma: {idioma}, Notificações: {notificacoes}")
# Por posição
configurar("escuro", "pt-BR", False)
# Por nome (ordem não importa)
configurar(idioma="en", tema="claro")
# Misto (posicionais primeiro, depois nomeados)
configurar("escuro", notificacoes=False, idioma="es")
4. Retornando Valores com return
Uso básico
A palavra-chave return encerra a execução da função e retorna um valor ao chamador.
def somar(a, b):
return a + b
resultado = somar(10, 20)
print(resultado) # Saída: 30
Retornando múltiplos valores
Python permite retornar múltiplos valores como uma tupla (implícita ou explícita).
def dividir(dividendo, divisor):
quociente = dividendo // divisor
resto = dividendo % divisor
return quociente, resto # Retorna uma tupla
q, r = dividir(17, 5)
print(f"Quociente: {q}, Resto: {r}") # Saída: Quociente: 3, Resto: 2
Funções sem return
Se uma função não possui return, ela retorna None implicitamente.
def mostrar_mensagem():
print("Esta função não retorna nada explicitamente.")
resultado = mostrar_mensagem()
print(resultado) # Saída: None
5. Escopo de Variáveis em Funções
Variáveis locais vs. globais
Variáveis definidas dentro de uma função são locais — existem apenas durante a execução da função. Variáveis definidas fora são globais e podem ser acessadas, mas não modificadas diretamente dentro da função.
x = 10 # Variável global
def funcao():
y = 5 # Variável local
print(f"Dentro: x = {x}, y = {y}")
funcao()
print(f"Fora: x = {x}")
# print(y) # Erro! y não existe fora da função
A palavra-chave global
Para modificar uma variável global dentro de uma função, é necessário declarar global.
contador = 0
def incrementar():
global contador
contador += 1
print(f"Contador: {contador}")
incrementar() # Saída: Contador: 1
incrementar() # Saída: Contador: 2
Acesso a variáveis do escopo externo
Funções aninhadas podem acessar variáveis do escopo externo (nonlocal).
def externa():
mensagem = "Olá"
def interna():
print(mensagem) # Acessa variável do escopo externo
interna()
externa() # Saída: Olá
6. Funções como Objetos de Primeira Classe
Em Python, funções são objetos de primeira classe: podem ser atribuídas a variáveis, passadas como argumentos e retornadas por outras funções.
Atribuindo funções a variáveis
def quadrado(n):
return n ** 2
minha_funcao = quadrado
print(minha_funcao(5)) # Saída: 25
Passando funções como argumentos
def aplicar_operacao(operacao, a, b):
return operacao(a, b)
def somar(x, y):
return x + y
def multiplicar(x, y):
return x * y
print(aplicar_operacao(somar, 3, 4)) # Saída: 7
print(aplicar_operacao(multiplicar, 3, 4)) # Saída: 12
Funções aninhadas (inner functions)
Funções podem ser definidas dentro de outras funções.
def criar_saudacao(saudacao):
def saudar(nome):
return f"{saudacao}, {nome}!"
return saudar
saudar_oi = criar_saudacao("Oi")
saudar_ola = criar_saudacao("Olá")
print(saudar_oi("Ana")) # Saída: Oi, Ana!
print(saudar_ola("João")) # Saída: Olá, João!
7. Boas Práticas com Funções
Nomes descritivos e verbos
Use verbos ou frases verbais que descrevam a ação da função.
# Ruim
def calc(x, y):
return x * y
# Bom
def calcular_area_retangulo(largura, altura):
return largura * altura
Funções pequenas e com responsabilidade única
Cada função deve fazer apenas uma coisa bem feita. Se uma função está fazendo múltiplas tarefas, considere dividi-la.
# Ruim: faz validação, processamento e formatação
def processar_usuario(dados):
if not dados.get("email"):
return "Erro"
nome = dados["nome"].upper()
return f"USUÁRIO: {nome}"
# Bom: funções separadas
def validar_dados(dados):
return "email" in dados
def formatar_nome(nome):
return nome.upper()
def processar_usuario(dados):
if not validar_dados(dados):
return "Erro"
return f"USUÁRIO: {formatar_nome(dados['nome'])}"
Evitando efeitos colaterais (side effects)
Prefira funções que recebem dados e retornam resultados, sem modificar variáveis globais ou argumentos mutáveis.
# Ruim: modifica a lista original
def adicionar_item_ruim(item, lista):
lista.append(item)
# Bom: retorna uma nova lista
def adicionar_item_bom(item, lista):
return lista + [item]
original = [1, 2, 3]
adicionar_item_ruim(4, original)
print(original) # Saída: [1, 2, 3, 4] - modificada!
original = [1, 2, 3]
nova = adicionar_item_bom(4, original)
print(original) # Saída: [1, 2, 3] - preservada
print(nova) # Saída: [1, 2, 3, 4]
Conclusão
Funções são o bloco de construção fundamental para código Python organizado e reutilizável. Dominar definição, chamada, parâmetros, retorno, escopo e boas práticas permite escrever programas mais claros, modulares e fáceis de manter. Pratique criando funções para tarefas do dia a dia e explore conceitos mais avançados como decoradores, geradores e closures.
Referências
- Documentação oficial: Definindo funções — Guia oficial da linguagem Python sobre definição de funções, parâmetros e escopo.
- Documentação oficial: Mais sobre definição de funções — Explica argumentos padrão, argumentos nomeados, listas de argumentos arbitrários e desempacotamento.
- Real Python: Defining Your Own Python Function — Tutorial completo com exemplos práticos sobre definição, parâmetros, retorno e escopo.
- GeeksforGeeks: Python Functions — Artigo detalhado com exemplos sobre todos os aspectos de funções em Python.
- W3Schools: Python Functions — Tutorial interativo com exercícios sobre definição, chamada, parâmetros e retorno de funções.
- Python.org: PEP 257 - Docstring Conventions — Convenções para escrever docstrings em funções, classes e módulos.