Funções são blocos de código reutilizáveis com um nome.
Elas funcionam como sub-rotinas que executam uma tarefa específica.
Primeiramente, funções evitam repetição de código (DRY).
Por exemplo, você escreve uma fórmula uma vez e reutiliza.
Além disso, funções dividem problemas grandes em partes menores.
A voz passiva é usada aqui: “o código é organizado em blocos lógicos”.
Quando utilizar funções como sub-rotinas? Em praticamente todo programa.
Também para isolar funcionalidades e facilitar testes.
Python usa def para definir funções.
Vamos explorar criação, parâmetros e retorno de valores.
Três subtítulos guiarão você pelo mundo das funções.
Ao final, você escreverá código modular e reutilizável.
Criando e chamando funções básicas
Use def nome(): para definir uma função.
O corpo da função fica indentado abaixo da definição.
Para executar a função, chame-a pelo nome com parênteses.
Quando usar funções simples? Para agrupar instruções relacionadas.
A voz passiva é aplicada: “os argumentos são passados entre parênteses”.
Exemplo de funções básicas:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# Função simples sem parâmetros def saudacao(): """Exibe uma saudação simples.""" print("Olá, bem-vindo ao Python!") # Função com um parâmetro def saudacao_personalizada(nome): """Saudação com o nome do usuário.""" print(f"Olá, {nome}!") # Função com retorno def somar(a, b): """Retorna a soma de dois números.""" return a + b # Função com múltiplos parâmetros def area_retangulo(largura, altura): """Calcula a área de um retângulo.""" return largura * altura # Chamando as funções print("=== Funções Básicas ===") saudacao() saudacao_personalizada("Ana") resultado = somar(10, 5) print(f"Soma: {resultado}") area = area_retangulo(8, 6) print(f"Área do retângulo: {area}") # Função com valor padrão def cumprimentar(nome, saudacao="Olá"): """Saudação com valor padrão.""" return f"{saudacao}, {nome}!" print(cumprimentar("Carlos")) print(cumprimentar("Maria", "Bom dia")) # Função que retorna múltiplos valores def operacoes_basicas(a, b): """Retorna soma, subtração, multiplicação e divisão.""" soma = a + b subtracao = a - b multiplicacao = a * b divisao = a / b if b != 0 else None return soma, subtracao, multiplicacao, divisao s, sub, m, d = operacoes_basicas(10, 3) print(f"\nOperações: soma={s}, sub={sub}, mult={m}, div={d:.2f}") |
Funções tornam o código mais organizado e legível. Cada função deve ter uma única responsabilidade clara.
Parâmetros: passando dados para funções
Parâmetros são variáveis que a função recebe para processar. Python suporta parâmetros posicionais e nomeados. Argumentos padrão tornam parâmetros opcionais. Quando usar diferentes tipos? Para flexibilidade na chamada. A voz passiva é aplicada: “os valores são passados na ordem definida”. Exemplo de parâmetros:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# Parâmetros posicionais (ordem importa) def descrever_pessoa(nome, idade, cidade): return f"{nome}, {idade} anos, mora em {cidade}" print("=== Parâmetros Posicionais ===") print(descrever_pessoa("Ana", 25, "São Paulo")) # Parâmetros nomeados (ordem não importa) print("\n=== Parâmetros Nomeados ===") print(descrever_pessoa(cidade="Rio", idade=30, nome="Carlos")) # Parâmetros com valores padrão def criar_usuario(nome, ativo=True, nivel="comum"): """Cria usuário com valores padrão.""" return {"nome": nome, "ativo": ativo, "nivel": nivel} print("\n=== Valores Padrão ===") print(criar_usuario("Ana")) print(criar_usuario("Carlos", ativo=False)) print(criar_usuario("Beatriz", nivel="admin")) # *args (número variável de argumentos posicionais) def soma_varios(*numeros): """Soma qualquer quantidade de números.""" return sum(numeros) print("\n=== *args (múltiplos argumentos) ===") print(f"soma_varios(1,2,3): {soma_varios(1, 2, 3)}") print(f"soma_varios(10,20,30,40): {soma_varios(10, 20, 30, 40)}") # **kwargs (número variável de argumentos nomeados) def exibir_dados(**dados): """Exibe dados nomeados recebidos.""" for chave, valor in dados.items(): print(f" {chave}: {valor}") print("\n=== **kwargs ===") exibir_dados(nome="Ana", idade=25, cidade="São Paulo") # Combinando parâmetros def funcao_completa(a, b, *args, opcao="padrao", **kwargs): print(f"a={a}, b={b}") print(f"args={args}") print(f"opcao={opcao}") print(f"kwargs={kwargs}") print("\n=== Função Completa ===") funcao_completa(1, 2, 3, 4, 5, opcao="especial", x=10, y=20) |
Parâmetros flexíveis tornam funções reutilizáveis. Escolha o tipo certo para cada situação.
Escopo, docstrings e boas práticas
Variáveis dentro da função são locais (escopo local).
Variáveis fora são globais (use global para modificar).
Docstrings documentam o propósito da função.
Quando usar escopo global? Evite ao máximo.
Prefira passar valores como parâmetros e retornar resultados.
A voz passiva é aplicada: “a documentação é gerada automaticamente”.
Exemplo de escopo e documentação:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# Escopo de variáveis mensagem_global = "Fora da função" def exemplo_escopo(): mensagem_local = "Dentro da função" global mensagem_global mensagem_global = "Modificada globalmente" print(f"Local: {mensagem_local}") print(f"Global dentro: {mensagem_global}") print("=== Escopo ===") print(f"Global antes: {mensagem_global}") exemplo_escopo() print(f"Global depois: {mensagem_global}") # Docstrings (documentação) def calcular_imposto(valor, aliquota=0.1): """ Calcula o imposto sobre um valor. Parâmetros: valor (float): O valor base para cálculo aliquota (float): Percentual do imposto (padrão 0.1 = 10%) Retorna: float: O valor do imposto calculado Exemplo: >>> calcular_imposto(1000, 0.15) 150.0 """ return valor * aliquota print("\n=== Docstrings ===") print(f"Imposto: R${calcular_imposto(1000):.2f}") print(f"Ajuda da função: {calcular_imposto.__doc__[:80]}...") # Boas práticas: funções pequenas e focadas def validar_email(email): """Valida formato básico de e-mail.""" return "@" in email and "." in email def formatar_nome(nome): """Formata nome com primeira letra maiúscula.""" return nome.strip().title() def criar_saudacao_completa(nome, email): """Cria saudação completa com validação.""" if not validar_email(email): return f"Olá {formatar_nome(nome)}, e-mail inválido!" return f"Olá {formatar_nome(nome)}, seu e-mail {email} está válido!" print("\n=== Boas Práticas ===") print(criar_saudacao_completa("ana silva", "ana@email.com")) print(criar_saudacao_completa("carlos", "carlos_invalido")) # Função como sub-rotina em pipeline def extrair_dados(texto): return texto.split() def limpar_dados(palavras): return [p.strip(".,!?").lower() for p in palavras] def contar_palavras(palavras): return len(palavras) def processar_texto(texto): """Pipeline de processamento de texto.""" dados = extrair_dados(texto) limpos = limpar_dados(dados) return contar_palavras(limpos) texto_exemplo = "Python é incrível! Python é poderoso." print(f"\nPipeline: {processar_texto(texto_exemplo)} palavras") |
Funções são o bloco de construção da programação modular. A fórmula da reutilização com funções: \(R = \frac{\text{código reutilizado}}{\text{código total}} \times 100\%\) Quanto maior, melhor o design do seu programa. Use funções para evitar repetição e organizar lógica. Cada função deve fazer uma coisa e fazer bem. Seu código será mais fácil de testar e manter.