⚙️ Funções Avançadas
Seções 8.4–8.9 — Parâmetros opcionais, nomeados, funções de ordem superior, empacotamento e lambda
🔧 8.4 Parâmetros Opcionais
Parâmetros opcionais (ou com valor padrão) tornam certos argumentos opcionários na chamada. Se o argumento não for fornecido, o valor padrão é usado:
Listagem 8.17 — Função barra simplesdef barra(largura):
print("=" * largura)
Listagem 8.18 — Barra com parâmetros opcionaisdef barra(largura=40, char="="):
print(char * largura)
Listagem 8.19 — Chamando barra de várias formasbarra()
barra(20)
barra(30, "-")
========================================
====================
------------------------------
Parâmetros opcionais também podem controlar o comportamento da função:
Listagem 8.20 — Parâmetro booleano opcionaldef soma(a, b, imprime=False):
resultado = a + b
if imprime:
print(f"{a} + {b} = {resultado}")
return resultado
Listagem 8.21 — Uso da função somax = soma(2, 3)
y = soma(2, 3, True)
z = soma(2, 3, imprime=True)
2 + 3 = 5
2 + 3 = 5
⚠️ Atenção: parâmetros com valor padrão devem sempre vir depois dos parâmetros obrigatórios. O código abaixo causa erro de sintaxe:
Listagem 8.22 — Definição INVÁLIDAdef soma(a=0, b):
return a + b
🏷️ 8.5 Nomeando Parâmetros
Ao chamar uma função, podemos nomear os argumentos para maior clareza e flexibilidade de ordem:
Listagem 8.23 — Função retângulodef retângulo(largura, altura, char="*", preenche=False):
for i in range(altura):
if preenche or i == 0 or i == altura - 1:
print(char * largura)
else:
print(char + " " * (largura - 2) + char)
Listagem 8.24 — Chamando com argumentos nomeadosretângulo(10, 4)
retângulo(10, 4, char="-")
retângulo(10, 4, preenche=True)
retângulo(altura=4, largura=10)
Listagem 8.25 — Chamadas inválidasretângulo(10) # TypeError: falta 'altura'
retângulo(10, 4, 3) # TypeError: 3 não é str
💡 Nomear argumentos torna o código mais legível, especialmente quando a função tem muitos parâmetros opcionais. Use nomes claros e descritivos.
🔁 8.6 Funções como Parâmetro
Em Python, funções são objetos de primeira classe — podem ser passadas como argumentos para outras funções. Isso permite criar código extremamente flexível:
Listagem 8.26 — Passando função como argumentodef aplica(func, valor):
return func(valor)
def dobro(x):
return x * 2
print(aplica(dobro, 5))
print(aplica(str, 42))
10
42
Um exemplo mais prático: uma função que imprime elementos de uma lista, com filtro e formato configuráveis:
Listagem 8.27 — imprime_lista com funções configuráveisdef imprime_lista(lista, fcondição=None, fimpressão=print):
for e in lista:
if fcondição is None or fcondição(e):
fimpressão(e)
def épar(n):
return n % 2 == 0
numeros = [1, 2, 3, 4, 5, 6]
imprime_lista(numeros)
imprime_lista(numeros, fcondição=épar)
1
2
3
4
5
6
---
2
4
6
📦 8.7 Empacotamento com *args
Quando uma função precisa aceitar um número variável de argumentos, usamos o prefixo * no parâmetro. Os argumentos extras são empacotados numa tupla:
Listagem 8.28 — soma com *argsdef soma(*args):
total = 0
for n in args:
total += n
return total
print(soma(1, 2))
print(soma(1, 2, 3, 4, 5))
print(soma())
3
15
0
Listagem 8.29 — Barra com *argsdef barra(*args):
if len(args) == 0:
print("=" * 40)
elif len(args) == 1:
print("=" * args[0])
else:
print(args[1] * args[0])
Misturando parâmetros obrigatórios e *args
Listagem 8.30 — Parâmetros fixos + *argsdef cabecalho(titulo, *subtitulos):
print("===", titulo, "===")
for s in subtitulos:
print(" -", s)
cabecalho("Python")
cabecalho("Python", "Rápido", "Legível", "Poderoso")
=== Python ===
=== Python ===
- Rápido
- Legível
- Poderoso
📤 8.8 Desempacotamento
O operador * também pode ser usado na chamada de uma função para desempacotar uma lista ou tupla em argumentos separados:
Listagem 8.31 — Desempacotando lista na chamadadef soma3(a, b, c):
return a + b + c
numeros = [10, 20, 30]
print(soma3(*numeros))
60
💡 Empacotamento (na definição): *args agrupa múltiplos argumentos em uma tupla. Desempacotamento (na chamada): *lista expande uma seqüência em argumentos separados.
λ 8.9 Funções Lambda
Uma função lambda é uma função anônima definida em uma única expressão. A sintaxe é: lambda parâmetros: expressão. São úteis quando precisamos de uma função simples por pouco tempo:
Listagem 8.32 — Lambda básicodobro = lambda x: x * 2
quadrado = lambda x: x ** 2
soma = lambda a, b: a + b
print(dobro(5))
print(quadrado(4))
print(soma(3, 7))
10
16
10
O uso mais comum de lambdas é como argumento para funções como sorted(), filter() e map():
Listagem 8.33 — Lambda com sorted e filternomes = ["Bruno", "Ana", "Carla", "Diego"]
por_tamanho = sorted(nomes, key=lambda n: len(n))
print(por_tamanho)
longos = list(filter(lambda n: len(n) > 4, nomes))
print(longos)
dobrados = list(map(lambda x: x * 2, [1, 2, 3, 4]))
print(dobrados)
['Ana', 'Bruno', 'Carla', 'Diego']
['Bruno', 'Carla', 'Diego']
[2, 4, 6, 8]
💡 Para funções simples de uma linha passadas como argumento, lambda é conciso e legível. Para funções mais complexas (com condicionais, loops, etc.), prefira def.