De def básico a decorators — tudo sobre funções com exemplos reais e boas práticas.
Funções são blocos de código reutilizáveis que executam uma tarefa específica. Em vez de repetir código, você cria uma função e reutiliza.
def saudacao():
print("Olá!")
saudacao() # chama a função
defPalavra-chave que define uma função
returnDevolve um valor ao chamador
parâmetroVariável declarada na função
argumentoValor passado ao chamar a função
def nome_da_funcao(parametros):
# código
return resultado
def somar(a, b): # a, b são parâmetros
return a + b
resultado = somar(2, 3) # 2, 3 são argumentos
print(resultado) # 5
1. Parâmetros obrigatórios:
def saudacao(nome):
print(f"Olá {nome}")
saudacao("Igor") # obrigatório passar o argumento
2. Parâmetros com valor padrão (default):
def saudacao(nome="Visitante"):
print(f"Olá {nome}")
saudacao() # Olá Visitante
saudacao("Igor") # Olá Igor
3. Argumentos nomeados (keyword args):
def pessoa(nome, idade):
print(nome, idade)
pessoa(idade=25, nome="Igor") # ordem não importa
4. *args — vários argumentos posicionais:
def soma(*numeros): # recebe qualquer qtd
return sum(numeros)
print(soma(1, 2, 3, 4)) # 10
print(soma(10, 20)) # 30
5. **kwargs — vários argumentos nomeados:
def mostrar_dados(**dados):
for chave, valor in dados.items():
print(chave, valor)
mostrar_dados(nome="Igor", idade=25, cidade="SP")
nome Igor
idade 25
cidade SP
SyntaxError.Com return:
def soma(a, b):
return a + b
resultado = soma(3, 4)
print(resultado) # 7
Sem return → retorna None:
def teste():
print("oi")
print(teste()) # oi
# None
Retornando múltiplos valores:
def operacoes(a, b):
return a + b, a * b # retorna uma tupla
soma, mult = operacoes(2, 3)
print(soma, mult) # 5 6
return ao invés de print dentro de funções. Funções com return são reutilizáveis e testáveis; com print, não.Variável local — existe apenas dentro da função:
def teste():
x = 10 # local
print(x)
teste()
# print(x) # ❌ NameError — x não existe aqui
Variável global — acessível dentro de qualquer função:
x = 5 # global
def teste():
print(x) # lê global — ok
teste() # 5
Modificando uma variável global:
x = 5
def alterar():
global x # declara intenção de modificar global
x = 10
alterar()
print(x) # 10
global sempre que possível. Ele dificulta a leitura e testes. Prefira passar o valor como parâmetro e retornar o resultado.Funções curtas de uma linha, sem nome, ideais para uso imediato.
# lambda parâmetros: expressão
dobro = lambda x: x * 2
print(dobro(5)) # 10
# equivale a:
def dobro(x):
return x * 2
Usando com map:
numeros = [1, 2, 3, 4]
dobrados = list(map(lambda x: x * 2, numeros))
print(dobrados) # [2, 4, 6, 8]
Usando com filter:
numeros = [1, 2, 3, 4, 5, 6]
pares = list(filter(lambda x: x % 2 == 0, numeros))
print(pares) # [2, 4, 6]
Usando com sorted:
pessoas = [("Igor", 25), ("Ana", 20), ("João", 30)]
ordenado = sorted(pessoas, key=lambda p: p[1])
print(ordenado)
# [('Ana', 20), ('Igor', 25), ('João', 30)]
Em Python, funções são cidadãos de primeira classe — você pode passá-las, retorná-las e guardá-las em variáveis.
def executar(func):
func()
def ola():
print("Olá!")
executar(ola) # Olá!
minha_func = print # sem parênteses = referência
minha_func("Olá!") # Olá!
def dobrar(x): return x * 2
def triplicar(x): return x * 3
operacoes = [dobrar, triplicar]
for op in operacoes:
print(op(5)) # 10, 15
Você pode definir funções dentro de outras funções — útil para organizar lógica interna.
def externa():
def interna():
print("Dentro da função interna")
interna() # chamada dentro da externa
print("Dentro da função externa")
externa()
Dentro da função interna
Dentro da função externa
interna só existe dentro de externa — ela não pode ser chamada de fora. Isso é a base para closures e decorators.Uma closure é uma função que "lembra" o contexto do seu ambiente externo, mesmo após a função externa ter terminado.
def multiplicador(x):
def multiplicar(y):
return x * y # lembra o x do contexto externo
return multiplicar
dobro = multiplicador(2)
triplo = multiplicador(3)
print(dobro(5)) # 10
print(triplo(5)) # 15
Decorators modificam ou estendem o comportamento de funções sem alterar o código original.
def log(func):
def wrapper(*args, **kwargs):
print(f"Executando: {func.__name__}")
resultado = func(*args, **kwargs)
print("Concluído!")
return resultado
return wrapper
@log # aplica o decorator
def somar(a, b):
return a + b
somar(2, 3)
Executando: somar
Concluído!
Decorator com argumentos:
def repetir(n):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
func(*args, **kwargs)
return wrapper
return decorator
@repetir(3)
def ola():
print("Olá!")
ola() # Olá! (3 vezes)
@log é açúcar sintático para somar = log(somar). Decorators são muito usados em frameworks como Flask e FastAPI para autenticação, rotas e validação.Type hints — documentam os tipos esperados (não enforce em runtime):
def soma(a: int, b: int) -> int:
return a + b
def saudacao(nome: str = "Visitante") -> None:
print(f"Olá {nome}")
def dividir(a: float, b: float) -> float | None:
return a / b if b != 0 else None
Docstrings — documentam o que a função faz:
def soma(a: int, b: int) -> int:
"""
Soma dois números inteiros.
Args:
a: Primeiro número.
b: Segundo número.
Returns:
A soma de a e b.
"""
return a + b
print(soma.__doc__) # acessa a docstring
help(soma) # exibe documentação formatada
Recursão — função que chama ela mesma:
def fatorial(n: int) -> int:
if n == 0:
return 1 # caso base
return n * fatorial(n - 1) # chamada recursiva
print(fatorial(5)) # 120 → 5 * 4 * 3 * 2 * 1
❌ Erros comuns:
# ❌ Esquecer return
def soma(a, b):
a + b # não retorna nada → None
# ❌ Ordem errada de parâmetros
def func(a=1, b): # SyntaxError
pass
# ❌ Mutabilidade perigosa no default
def adicionar(lista=[]): # mesmo objeto reutilizado!
lista.append(1)
return lista
# ✅ Correto
def adicionar(lista=None):
if lista is None:
lista = []
lista.append(1)
return lista
🎯 Exemplo prático completo:
def filtrar_pares(numeros: list) -> list:
"""Retorna apenas os números pares."""
return [n for n in numeros if n % 2 == 0]
def somar_lista(numeros: list) -> int:
"""Soma todos os elementos."""
return sum(numeros)
def pipeline(*funcs):
"""Aplica funções em sequência."""
def executar(dados):
for func in funcs:
dados = func(dados)
return dados
return executar
processar = pipeline(filtrar_pares, somar_lista)
lista = [1, 2, 3, 4, 5, 6]
print(processar(lista)) # 12 (2+4+6)
✔ Boas práticas:
calcular_total, buscar_usuarioreturn ao invés de print dentro de funçõesdef básico → parâmetros e retorno → *args/**kwargs → escopo → lambda → closures → decorators