Funções em Python
Introdução
Funções são blocos de código reutilizáveis que realizam uma tarefa específica. Elas permitem organizar o código, evitar repetições e facilitar a manutenção. As funções são um dos conceitos fundamentais da programação e um pilar da programação modular.
Objetivos de Aprendizado
- Entender o conceito e a importância das funções
- Aprender a definir e chamar funções
- Compreender parâmetros e argumentos
- Explorar o retorno de valores
- Dominar técnicas avançadas como funções anônimas (lambda)
- Aplicar funções em situações práticas
Definindo Funções
Em Python, funções são definidas com a palavra-chave def
, seguida do nome da função e de parênteses que podem conter parâmetros.
Boas Práticas
- Use nomes descritivos para funções (verbos que indiquem ação)
- Siga a convenção snake_case para nomes de funções em Python
- Inclua docstrings para documentar o propósito da função
- Mantenha funções pequenas e focadas em uma única tarefa
Parâmetros e Argumentos
Parâmetros são variáveis listadas na definição da função. Argumentos são os valores reais passados para a função quando ela é chamada.
def saudacao(nome, mensagem):
"""Cria uma saudação personalizada."""
return f"{mensagem}, {nome}!"
# Argumentos nomeados (a ordem não importa)
msg = saudacao(mensagem="Bom dia", nome="Ana")
print(msg) # Saída: Bom dia, Ana!
# Misturando posicionais e nomeados
# Posicionais vêm primeiro, depois os nomeados
msg = saudacao("Carlos", mensagem="Boa tarde")
print(msg) # Saída: Boa tarde, Carlos!
Parâmetros Padrão
Os parâmetros podem ter valores padrão que são usados quando um argumento não é fornecido.
Cuidado com Valores Padrão Mutáveis
Nunca use tipos mutáveis (como listas ou dicionários) como valores padrão. Eles são avaliados apenas uma vez, quando a função é definida.
Número Variável de Argumentos
Python permite definir funções que aceitam um número variável de argumentos.
def minha_funcao(arg1, arg2, *args, kwarg1="default", **kwargs):
"""Demonstra todos os tipos de argumentos."""
print(f"arg1: {arg1}")
print(f"arg2: {arg2}")
print(f"args: {args}")
print(f"kwarg1: {kwarg1}")
print(f"kwargs: {kwargs}")
minha_funcao(1, 2, 3, 4, 5, kwarg1="personalizado", x=10, y=20)
# Saída:
# arg1: 1
# arg2: 2
# args: (3, 4, 5)
# kwarg1: personalizado
# kwargs: {'x': 10, 'y': 20}
Retorno de Valores
A instrução return
é usada para especificar o valor que uma função deve retornar. Uma função pode retornar zero, um ou múltiplos valores.
Escopo de Variáveis
As variáveis em Python têm diferentes escopos (visibilidade), dependendo de onde são definidas.
contador = 0
def incrementar():
global contador # Declara que contador se refere à variável global
contador += 1
print(f"Contador dentro da função: {contador}")
print(f"Contador antes: {contador}") # Saída: Contador antes: 0
incrementar() # Saída: Contador dentro da função: 1
print(f"Contador depois: {contador}") # Saída: Contador depois: 1
def externa():
x = 10
def interna():
nonlocal x # Refere-se à variável x da função externa
x += 5
print(f"x dentro da função interna: {x}")
print(f"x antes da função interna: {x}")
interna()
print(f"x depois da função interna: {x}")
externa()
# Saída:
# x antes da função interna: 10
# x dentro da função interna: 15
# x depois da função interna: 15
Funções Anônimas (Lambda)
Funções lambda são pequenas funções anônimas definidas com a palavra-chave lambda
. Elas podem ter qualquer número de argumentos, mas apenas uma expressão.
# Ordenando uma lista de tuplas pelo segundo elemento
pares = [(1, 'um'), (3, 'três'), (2, 'dois'), (4, 'quatro')]
# Usando lambda como função de chave para sorted()
pares_ordenados = sorted(pares, key=lambda x: x[1])
print(pares_ordenados) # [(4, 'quatro'), (2, 'dois'), (3, 'três'), (1, 'um')]
# Usando com filter()
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pares = list(filter(lambda x: x % 2 == 0, numeros))
print(pares) # [2, 4, 6, 8, 10]
# Usando com map()
quadrados = list(map(lambda x: x ** 2, numeros))
print(quadrados) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Quando Usar Lambda vs. Funções Regulares
Use lambdas para funções simples e de uso único. Para lógica mais complexa ou código reutilizável, prefira funções regulares definidas com def
.
Recursividade
Uma função recursiva é uma função que chama a si mesma dentro de sua definição.
Cuidado com Recursão Profunda
Python tem um limite padrão para a profundidade da recursão (normalmente 1000). Para cálculos complexos, considere abordagens iterativas ou otimizações como memoização.
Funções como Objetos de Primeira Classe
Em Python, funções são objetos de primeira classe, o que significa que podem ser: - Atribuídas a variáveis - Passadas como argumentos para outras funções - Retornadas por outras funções - Armazenadas em estruturas de dados
Decoradores
Decoradores são funções que modificam o comportamento de outras funções. Eles permitem estender ou alterar o comportamento de funções sem modificar seu código.
def meu_decorador(func):
def wrapper():
print("Algo antes da função original")
func()
print("Algo depois da função original")
return wrapper
@meu_decorador
def funcao():
print("Função original executada")
# Chamando a função decorada
funcao()
# Saída:
# Algo antes da função original
# Função original executada
# Algo depois da função original
def meu_decorador(func):
def wrapper(*args, **kwargs):
print("Antes da função")
resultado = func(*args, **kwargs)
print("Depois da função")
return resultado
return wrapper
@meu_decorador
def soma(a, b):
print(f"Somando {a} + {b}")
return a + b
resultado = soma(3, 5)
print(f"Resultado: {resultado}")
# Saída:
# Antes da função
# Somando 3 + 5
# Depois da função
# Resultado: 8
def repetir(n):
def decorador(func):
def wrapper(*args, **kwargs):
for _ in range(n):
resultado = func(*args, **kwargs)
return resultado
return wrapper
return decorador
@repetir(3)
def saudacao(nome):
print(f"Olá, {nome}!")
return nome
saudacao("Maria")
# Saída:
# Olá, Maria!
# Olá, Maria!
# Olá, Maria!
Geradores
Geradores são funções especiais que retornam um iterador. Eles usam a palavra-chave yield
em vez de return
para fornecer valores um por vez, mantendo o estado da função entre chamadas.
Vantagens dos Geradores
- Eficiência de memória: geram valores sob demanda, não armazenam todos na memória
- Úteis para sequências infinitas ou muito grandes
- Mantêm o estado entre chamadas
Funções Integradas (Built-in)
Python possui diversas funções integradas que são sempre disponíveis.
# len() - comprimento de um objeto
print(len("Python")) # Saída: 6
# range() - sequência de números
lista = list(range(1, 6))
print(lista) # Saída: [1, 2, 3, 4, 5]
# type() - tipo do objeto
print(type(123)) # Saída: <class 'int'>
print(type("texto")) # Saída: <class 'str'>
# map() - aplica função a cada item de um iterável
numeros = [1, 2, 3, 4]
quadrados = list(map(lambda x: x**2, numeros))
print(quadrados) # Saída: [1, 4, 9, 16]
# filter() - filtra itens por uma função
numeros = [1, 2, 3, 4, 5, 6]
pares = list(filter(lambda x: x % 2 == 0, numeros))
print(pares) # Saída: [2, 4, 6]
# sorted() - retorna lista ordenada
frutas = ["banana", "maçã", "laranja"]
ordenadas = sorted(frutas)
print(ordenadas) # Saída: ['banana', 'laranja', 'maçã']
Lista Completa
Consulte a documentação oficial para uma lista completa das funções integradas em Python.
Boas Práticas
# RUIM: função faz várias coisas
def processar_dados(dados):
# Limpa dados
# Calcula estatísticas
# Gera gráficos
# Salva resultados
pass
# BOM: funções separadas para cada responsabilidade
def limpar_dados(dados):
return dados_limpos
def calcular_estatisticas(dados_limpos):
return estatisticas
def gerar_graficos(estatisticas):
return graficos
def salvar_resultados(estatisticas, graficos):
pass
def calcular_media(numeros):
"""
Calcula a média aritmética de uma sequência de números.
Args:
numeros (list): Uma lista de números.
Returns:
float: A média aritmética dos números.
Raises:
ValueError: Se a lista estiver vazia.
Examples:
>>> calcular_media([1, 2, 3, 4, 5])
3.0
"""
if not numeros:
raise ValueError("A lista não pode estar vazia")
return sum(numeros) / len(numeros)
Resumo
Nesta aula, você aprendeu sobre:
- Definição de funções com a palavra-chave
def
- Parâmetros e argumentos, incluindo argumentos posicionais, nomeados e valores padrão
- Número variável de argumentos com
*args
e**kwargs
- Retorno de valores com a instrução
return
- Escopo de variáveis (local, global e nonlocal)
- Funções anônimas (lambda) para expressões simples
- Recursividade para resolver problemas que se decompõem em problemas menores
- Funções como objetos de primeira classe
- Decoradores para modificar o comportamento de funções
- Geradores para criar iteradores de forma eficiente
- Funções integradas do Python
- Boas práticas para escrever funções claras e eficientes
Recursos de aprendizado
Próximos Passos
Na próxima aula, exploraremos a programação orientada a objetos em Python, incluindo classes, objetos, herança e polimorfismo.