Módulos
Esta aula aborda o uso de módulos em Python, desde a importação básica até técnicas avançadas de organização de código. Você aprenderá as diferentes formas de importar, a importância da variável __name__ e boas práticas para estruturar projetos modulares.
Nesta aula, vamos explorar o conceito de módulos em Python, que são arquivos contendo definições e instruções que podem ser reutilizados em outros programas. Módulos são fundamentais para organizar código, evitar repetição e facilitar a manutenção. Você aprenderá a importar módulos de várias maneiras, a entender o comportamento da variável especial __name__ e a estruturar seus projetos de forma eficiente.
Dominar módulos é essencial para qualquer programador Python, pois permite construir aplicações maiores e mais complexas de maneira organizada. Vamos começar com o básico e progredir para tópicos mais avançados, com exemplos práticos que você pode testar em seu próprio ambiente.
import
A instrução import é a forma mais simples de usar um módulo em Python. Quando você escreve import nome_do_modulo, o interpretador procura pelo arquivo nome_do_modulo.py nos diretórios listados na variável sys.path e o executa, disponibilizando suas funções, classes e variáveis no namespace atual, mas acessíveis apenas através da sintaxe modulo.nome.
Por exemplo, o módulo padrão math fornece funções matemáticas. Para usá-lo, fazemos:
import math
print(math.sqrt(16)) # 4.0Isso evita conflitos de nomes, pois todas as referências ao módulo são qualificadas. É uma boa prática para evitar ambiguidades, especialmente em projetos grandes.
Formas de importar
Existem várias formas de importar módulos, cada uma com suas vantagens e desvantagens. A primeira é a importação direta de itens específicos usando from ... import .... Isso permite usar o nome diretamente, sem o prefixo do módulo:
from math import sqrt
print(sqrt(25)) # 5.0Você também pode importar múltiplos itens de uma vez: from math import sqrt, pi. Outra forma é usar um alias, útil para nomes longos: import numpy as np. Isso é comum em bibliotecas como pandas e numpy.
Há ainda a importação de todos os itens com from math import *, que não é recomendado porque pode poluir o namespace e causar conflitos. Prefira sempre importar apenas o que você precisa.
__name__ == "__main__"
A variável __name__ é uma variável especial que o Python define em cada módulo. Quando um módulo é executado diretamente (como script principal), __name__ é definido como a string "__main__". Quando o módulo é importado, __name__ é definido como o nome do módulo (sem a extensão .py).
Essa distinção é crucial para escrever código que pode ser tanto executado diretamente quanto importado sem efeitos colaterais indesejados. O padrão comum é:
def main():
print("Executando diretamente")
if __name__ == "__main__":
main()Assim, se o arquivo for executado como script, a função main() roda; se for importado, ela não roda, permitindo que outras partes do código usem as funções definidas sem executar ações desnecessárias.
Organização
Organizar seu código em módulos é uma prática essencial para projetos escaláveis. Uma boa estrutura pode incluir uma pasta para o projeto, com subpastas para módulos relacionados. Por exemplo:
meu_projeto/
__init__.py
main.py
utils/
__init__.py
helpers.py
models/
__init__.py
usuario.pyO arquivo __init__.py pode estar vazio, mas indica que a pasta é um pacote Python. Você pode importar módulos de pacotes usando a notação de ponto: from utils.helpers import funcao.
Além disso, é importante manter módulos pequenos e com responsabilidade única. Isso facilita a leitura, testes e manutenção. Evite colocar muitas funcionalidades em um único arquivo; divida em módulos coesos.
Boas práticas
Algumas boas práticas ao trabalhar com módulos: use nomes descritivos para seus módulos, evite importações circulares (quando dois módulos se importam mutuamente), e sempre coloque a lógica de execução dentro de if __name__ == "__main__": para permitir reutilização.
Também é recomendado usar aliases para bibliotecas comuns, mas com moderação. E lembre-se de que a importação de um módulo executa seu código no topo, então evite efeitos colaterais no nível do módulo.
Exercícios
- Crie um módulo chamado
operacoes.pycom funções para somar, subtrair, multiplicar e dividir. Em outro arquivo, importe e use essas funções. - Escreva um script que use
from math import factoriale calcule o fatorial de 5. - Explique o que acontece quando você executa um módulo diretamente vs importá-lo, em relação ao
__name__. - Crie um pacote chamado
meu_pacotecom dois módulos:modulo1.pyemodulo2.py. No primeiro, defina uma funçãoola(); no segundo, importe e chame essa função. - Refatore o código a seguir para usar módulos: suponha que você tenha funções de validação de email e CPF. Coloque-as em um módulo
validacoes.pye importe-as em um arquivo principal.
# operacoes.py
def soma(a, b):
return a + b
def subtracao(a, b):
return a - b
def multiplicacao(a, b):
return a * b
def divisao(a, b):
if b == 0:
raise ValueError("Divisão por zero")
return a / b
# uso.py
import operacoes
print(operacoes.soma(10, 5))
print(operacoes.divisao(10, 2))from math import factorial
print(factorial(5)) # 120__name__ é "__main__"; quando importado, é o nome do módulo. Isso permite controlar se o código deve rodar ou não.# meu_pacote/__init__.py (vazio)
# meu_pacote/modulo1.py
def ola():
print("Olá!")
# meu_pacote/modulo2.py
from meu_pacote.modulo1 import ola
ola()# validacoes.py
def valida_email(email):
return "@" in email
def valida_cpf(cpf):
return len(cpf) == 11
# main.py
from validacoes import valida_email, valida_cpf
print(valida_email("teste@exemplo.com"))
print(valida_cpf("12345678901"))