Funções em Python
LidoNesta aula, você aprenderá a definir funções em Python usando a palavra-chave def, a trabalhar com parâmetros e retornos, a documentar suas funções com docstrings e a entender o escopo de variáveis. Através de exemplos práticos e exercícios, você dominará a criação de código modular e reutilizável.
Funções são blocos de código reutilizáveis que executam uma tarefa específica. Em Python, funções são definidas com a palavra-chave def e são fundamentais para organizar programas em partes lógicas, evitar repetição e facilitar a manutenção. Nesta aula, vamos explorar os principais aspectos de funções: como defini-las, passar parâmetros, retornar valores, documentá-las adequadamente e entender como o escopo de variáveis funciona.
Dominar funções é essencial para qualquer programador Python, pois elas permitem criar código modular, testável e legível. Vamos começar com a sintaxe básica e evoluir para conceitos mais avançados.
def
A palavra-chave def é usada para definir uma função. A sintaxe básica é:
def nome_da_funcao(parametros):
# corpo da função
# pode conter várias linhas
return valor_opcional
O nome da função deve seguir as regras de identificadores (geralmente letras minúsculas com underscores para separar palavras). A definição é seguida por parênteses que podem conter parâmetros (opcionais) e dois-pontos. O corpo deve ser indentado (geralmente 4 espaços). A função pode ou não retornar um valor com return. Se não houver return, a função retorna None implicitamente.
def saudacao():
print("Olá, mundo!")
saudacao() # Chama a função
Funções podem ser chamadas quantas vezes forem necessárias, tornando o código mais limpo e evitando duplicação.
Parâmetros e retorno
Parâmetros são valores que a função recebe para trabalhar. Eles são definidos entre parênteses na declaração da função. Os argumentos são os valores passados na chamada. Python suporta vários tipos de parâmetros:
- Parâmetros posicionais: a ordem importa.
- Parâmetros nomeados (keyword arguments): passados com nome, permitindo ordem diferente.
- Valores padrão: você pode definir um valor padrão para um parâmetro, tornando-o opcional.
- *args e **kwargs: para número variável de argumentos posicionais e nomeados.
def soma(a, b):
return a + b
print(soma(2, 3)) # 5
print(soma(b=4, a=1)) # 5 (nomeados)
def cumprimentar(nome, saudacao="Olá"):
return f"{saudacao}, {nome}!"
print(cumprimentar("Maria")) # Olá, Maria!
print(cumprimentar("João", "Oi")) # Oi, João!
O retorno é feito com a instrução return. Uma função pode retornar múltiplos valores como tupla. O return também encerra a execução da função imediatamente.
def dividir(a, b):
quociente = a // b
resto = a % b
return quociente, resto
q, r = dividir(10, 3)
print(q, r) # 3 1
Docstrings
Docstrings são strings de documentação que descrevem o propósito da função, seus parâmetros e o que retorna. Elas são colocadas imediatamente após a linha def antes do corpo, entre aspas triplas. São acessíveis via help(nome_da_funcao) ou nome_da_funcao.__doc__. Boas docstrings seguem convenções como a PEP 257.
def soma(a, b):
"""
Retorna a soma de dois números.
Args:
a (int/float): Primeiro número.
b (int/float): Segundo número.
Returns:
int/float: A soma de a e b.
"""
return a + b
print(soma.__doc__)
Docstrings são importantes para documentação automática e para outros programadores entenderem sua função sem ler o código.
Escopo
Escopo refere-se à visibilidade e ao tempo de vida das variáveis. Em Python, variáveis definidas dentro de uma função têm escopo local, ou seja, não podem ser acessadas fora dela. Variáveis definidas fora de qualquer função têm escopo global. Para modificar uma variável global dentro de uma função, usamos a palavra-chave global (ou nonlocal para escopo aninhado).
x = 10 # global
def modificar_global():
global x
x = 20
modificar_global()
print(x) # 20
É importante entender que, por padrão, atribuir a uma variável dentro de uma função cria uma variável local, mesmo que exista uma global com o mesmo nome. Isso evita efeitos colaterais indesejados. Boa prática: evitar o uso excessivo de variáveis globais, preferindo passar valores como parâmetros e retornar resultados.
def exemplo_escopo():
y = 5 # local
return y
print(exemplo_escopo()) # 5
# print(y) # NameError: name 'y' is not defined
Boas práticas e observações finais
Ao escrever funções, siga estas recomendações:
- Use nomes descritivos e em minúsculas com palavras separadas por underscore.
- Mantenha as funções pequenas e com responsabilidade única.
- Sempre documente com docstrings.
- Evite variáveis globais, prefira parâmetros e retornos.
- Use
returnconsistente: ou sempre retorne algo, ou sempre não retorne. - Prefira funções puras (sem efeitos colaterais) sempre que possível.
Essas práticas tornam o código mais legível, testável e fácil de manter.
Exercícios
- Exercício 1: Escreva uma função chamada
par_ou_imparque recebe um número e retorna a string "par" se o número for par, e "ímpar" se for ímpar. Teste com alguns valores.✓ Resposta:def par_ou_impar(num): if num % 2 == 0: return "par" else: return "ímpar" print(par_ou_impar(4)) # par print(par_ou_impar(7)) # ímpar - Exercício 2: Crie uma função
area_retanguloque recebe largura e altura e retorna a área. Adicione uma docstring adequada. Teste com valores decimais.✓ Resposta:def area_retangulo(largura, altura): """ Calcula a área de um retângulo. Args: largura (float): Largura do retângulo. altura (float): Altura do retângulo. Returns: float: Área calculada (largura * altura). """ return largura * altura print(area_retangulo(5.0, 3.0)) # 15.0 - Exercício 3: Escreva uma função
contagem_regressivaque recebe um númerone imprime uma contagem regressiva de n até 1, e depois imprime "Lançar!". Use um loopwhile. Não retorne nada.✓ Resposta:def contagem_regressiva(n): while n > 0: print(n) n -= 1 print("Lançar!") contagem_regressiva(3) - Exercício 4: Defina uma função
soma_listaque recebe uma lista de números e retorna a soma deles. Use um loopfor. Não use a funçãosum().✓ Resposta:def soma_lista(lista): total = 0 for num in lista: total += num return total print(soma_lista([1, 2, 3, 4])) # 10 - Exercício 5: Explique o que o código abaixo imprime e por quê. Considere o escopo das variáveis.
x = 50 def func(): x = 10 return x print(x) # ? print(func()) # ? print(x) # ?✓ Resposta: Imprime 50, 10, 50. A primeira impressão mostra a variável global x (50). Dentro da função, a atribuição x = 10 cria uma variável local, então a função retorna 10. Após a chamada da função, a variável global x permanece inalterada, então a terceira impressão é 50. Isso demonstra que atribuições dentro de funções não afetam variáveis globais a menos que usemosglobal.