Módulos e pacotes são a forma como Python organiza e reutiliza código. Eles permitem dividir programas grandes em partes menores e mais gerenciáveis, além de dar acesso a milhares de bibliotecas criadas pela comunidade. Neste guia completo, você aprenderá a criar, importar e gerenciar módulos e pacotes como um profissional.
🎯 O Que São Módulos?
Um módulo é simplesmente um arquivo Python (`.py`) que contém código - funções, classes, variáveis - que pode ser reutilizado em outros programas. Pense em módulos como "cápsulas de funcionalidade" que você pode importar quando precisar.
# Arquivo: calculadora.py (este é um módulo!)
def somar(a, b):
"""Soma dois números"""
return a + b
def subtrair(a, b):
"""Subtrai dois números"""
return a - b
def multiplicar(a, b):
"""Multiplica dois números"""
return a * b
def dividir(a, b):
"""Divide dois números"""
if b == 0:
raise ValueError("Não é possível dividir por zero!")
return a / b
PI = 3.14159
VERSAO = "1.0.0"
📦 Importando Módulos
Import Simples
# Importar módulo inteiro
import calculadora
# Usar prefixando com nome do módulo
resultado = calculadora.somar(10, 5)
print(resultado) # 15
print(calculadora.PI) # 3.14159
Import com Alias
# Importar com apelido (alias)
import calculadora as calc
resultado = calc.multiplicar(4, 5)
print(resultado) # 20
From...Import
# Importar itens específicos
from calculadora import somar, dividir, PI
# Usar diretamente sem prefixo
resultado = somar(10, 5)
print(resultado) # 15
print(PI) # 3.14159
# Importar com alias
from calculadora import multiplicar as mult
print(mult(3, 4)) # 12
Importar Tudo (*)
# Importar tudo (NÃO recomendado!)
from calculadora import *
# Pode causar conflitos de nomes
resultado = somar(1, 2)
# ❌ Evite! Use imports explícitos
📚 Módulos Nativos do Python
Python vem com uma vasta biblioteca padrão. Aqui estão alguns módulos essenciais:
math - Operações Matemáticas
import math
# Constantes
print(math.pi) # 3.141592653589793
print(math.e) # 2.718281828459045
# Funções
print(math.sqrt(16)) # 4.0 (raiz quadrada)
print(math.pow(2, 8)) # 256.0 (potência)
print(math.ceil(4.3)) # 5 (arredonda para cima)
print(math.floor(4.7)) # 4 (arredonda para baixo)
print(math.factorial(5)) # 120
random - Números Aleatórios
import random
# Número aleatório entre 0 e 1
print(random.random()) # 0.7234...
# Inteiro aleatório em um intervalo
print(random.randint(1, 100)) # 42
# Escolher elemento aleatório de uma lista
cores = ["vermelho", "azul", "verde"]
print(random.choice(cores)) # "azul"
# Embaralhar lista
numeros = [1, 2, 3, 4, 5]
random.shuffle(numeros)
print(numeros) # [3, 1, 5, 2, 4]
# Amostra aleatória
print(random.sample(range(100), 5)) # [23, 67, 12, 89, 45]
datetime - Data e Hora
from datetime import datetime, date, timedelta
# Data/hora atual
agora = datetime.now()
print(agora) # 2026-01-08 08:12:43.123456
# Apenas data
hoje = date.today()
print(hoje) # 2026-01-08
# Criar data específica
nascimento = date(1990, 5, 15)
print(nascimento)
# Formatação
print(agora.strftime("%d/%m/%Y %H:%M")) # 08/01/2026 08:12
# Operações com datas
amanha = hoje + timedelta(days=1)
semana_passada = hoje - timedelta(weeks=1)
# Diferença entre datas
idade = hoje - nascimento
print(f"Dias vividos: {idade.days}")
os - Sistema Operacional
import os
# Diretório atual
print(os.getcwd())
# Listar arquivos
arquivos = os.listdir(".")
print(arquivos)
# Criar diretório
os.makedirs("nova_pasta", exist_ok=True)
# Verificar existência
print(os.path.exists("arquivo.txt"))
print(os.path.isfile("arquivo.txt"))
print(os.path.isdir("pasta"))
# Variáveis de ambiente
print(os.environ.get("PATH"))
print(os.environ.get("HOME"))
json - Trabalhar com JSON
Como vimos no guia de arquivos:
import json
# Dict para JSON string
dados = {"nome": "Python", "versao": 3.12}
json_string = json.dumps(dados, indent=2)
print(json_string)
# JSON string para dict
texto = '{"ativo": true, "valor": 42}'
objeto = json.loads(texto)
print(objeto["valor"]) # 42
# Salvar em arquivo
with open("dados.json", "w") as f:
json.dump(dados, f, indent=2)
# Ler de arquivo
with open("dados.json", "r") as f:
carregado = json.load(f)
📦 O Que São Pacotes?
Um pacote é uma coleção de módulos organizados em diretórios. É uma pasta que contém um arquivo especial __init__.py (pode estar vazio) que indica ao Python que aquela pasta é um pacote.
# Estrutura de um pacote
meu_projeto/
├── __init__.py
├── calculadora/
│ ├── __init__.py
│ ├── basica.py
│ ├── cientifica.py
│ └── financeira.py
├── utils/
│ ├── __init__.py
│ ├── validacao.py
│ └── formatacao.py
└── main.py
Criando um Pacote
# calculadora/__init__.py
"""Pacote de calculadoras"""
from .basica import somar, subtrair
from .cientifica import raiz_quadrada, potencia
__version__ = "1.0.0"
__all__ = ["somar", "subtrair", "raiz_quadrada", "potencia"]
# calculadora/basica.py
def somar(a, b):
return a + b
def subtrair(a, b):
return a - b
# calculadora/cientifica.py
import math
def raiz_quadrada(n):
return math.sqrt(n)
def potencia(base, exp):
return math.pow(base, exp)
Importando de Pacotes
# Importar pacote inteiro
import calculadora
print(calculadora.somar(1, 2))
# Importar módulo específico
from calculadora import cientifica
print(cientifica.raiz_quadrada(16))
# Importar função específica
from calculadora.basica import somar
print(somar(5, 3))
# Importar com alias
from calculadora import financeira as fin
print(fin.juros_compostos(1000, 0.05, 12))
🛠️ Pip - Gerenciador de Pacotes
O pip é a ferramenta padrão para instalar pacotes externos do PyPI (Python Package Index).
Comandos Básicos
# Instalar pacote
pip install requests
# Instalar versão específica
pip install requests==2.28.0
# Atualizar pacote
pip install --upgrade requests
# Desinstalar
pip uninstall requests
# Listar pacotes instalados
pip list
# Mostrar informações do pacote
pip show requests
# Verificar pacotes desatualizados
pip list --outdated
Requirements.txt
# Gerar arquivo de dependências
pip freeze > requirements.txt
# Instalar todas as dependências
pip install -r requirements.txt
# Exemplo de requirements.txt
requests==2.28.0
pandas>=1.5.0
numpy~=1.24.0
flask
🌐 Pacotes Externos Populares
| Pacote | Uso | Instalação |
|---|---|---|
requests |
Requisições HTTP | pip install requests |
pandas |
Análise de dados | pip install pandas |
numpy |
Computação numérica | pip install numpy |
flask |
Web framework | pip install flask |
django |
Web framework completo | pip install django |
pytest |
Testes automatizados | pip install pytest |
pillow |
Manipulação de imagens | pip install pillow |
beautifulsoup4 |
Web scraping | pip install beautifulsoup4 |
🎯 Projeto Prático: Criando um Pacote Completo
Vamos criar um pacote utilitário completo usando POO e boas práticas:
# Estrutura do projeto
universo_utils/
├── universo_utils/
│ ├── __init__.py
│ ├── validadores.py
│ ├── formatadores.py
│ ├── calculadora.py
│ └── api.py
├── tests/
│ ├── __init__.py
│ └── test_validadores.py
├── examples/
│ └── exemplo_uso.py
├── requirements.txt
├── setup.py
└── README.md
# universo_utils/__init__.py
"""
Universo Utils - Pacote de utilidades Python
"""
from .validadores import ValidadorEmail, ValidadorCPF, ValidadorSenha
from .formatadores import formatar_cpf, formatar_telefone, formatar_moeda
from .calculadora import Calculadora
__version__ = "1.0.0"
__author__ = "Universo Python"
__all__ = [
"ValidadorEmail",
"ValidadorCPF",
"ValidadorSenha",
"formatar_cpf",
"formatar_telefone",
"formatar_moeda",
"Calculadora"
]
# universo_utils/validadores.py
"""Módulo de validadores"""
import re
class ValidadorEmail:
"""Valida endereços de email"""
PADRAO = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
@classmethod
def validar(cls, email: str) -> bool:
"""Valida se o email está em formato correto"""
if not email or not isinstance(email, str):
return False
return bool(re.match(cls.PADRAO, email))
@classmethod
def extrair_dominio(cls, email: str) -> str:
"""Extrai o domínio do email"""
if cls.validar(email):
return email.split("@")[1]
return ""
class ValidadorCPF:
"""Valida CPFs brasileiros"""
@classmethod
def validar(cls, cpf: str) -> bool:
"""Valida um CPF"""
# Remover caracteres não numéricos
cpf = re.sub(r'[^0-9]', '', cpf)
# Verificar tamanho
if len(cpf) != 11:
return False
# CPFs inválidos conhecidos
if cpf == cpf[0] * 11:
return False
# Calcular primeiro dígito verificador
soma = sum(int(cpf[i]) * (10 - i) for i in range(9))
resto = soma % 11
digito1 = 0 if resto < 2 else 11 - resto
if int(cpf[9]) != digito1:
return False
# Calcular segundo dígito verificador
soma = sum(int(cpf[i]) * (11 - i) for i in range(10))
resto = soma % 11
digito2 = 0 if resto < 2 else 11 - resto
return int(cpf[10]) == digito2
class ValidadorSenha:
"""Valida força de senhas"""
@classmethod
def validar(cls, senha: str, min_tamanho: int = 8) -> dict:
"""
Valida senha e retorna análise completa
Returns:
dict com 'valida', 'score', 'feedback'
"""
resultado = {
"valida": False,
"score": 0,
"feedback": []
}
if len(senha) < min_tamanho:
resultado["feedback"].append(f"Mínimo {min_tamanho} caracteres")
else:
resultado["score"] += 1
if re.search(r'[a-z]', senha):
resultado["score"] += 1
else:
resultado["feedback"].append("Adicione letras minúsculas")
if re.search(r'[A-Z]', senha):
resultado["score"] += 1
else:
resultado["feedback"].append("Adicione letras maiúsculas")
if re.search(r'[0-9]', senha):
resultado["score"] += 1
else:
resultado["feedback"].append("Adicione números")
if re.search(r'[!@#$%^&*(),.?":{}|<>]', senha):
resultado["score"] += 1
else:
resultado["feedback"].append("Adicione caracteres especiais")
resultado["valida"] = resultado["score"] >= 4
return resultado
# universo_utils/formatadores.py
"""Módulo de formatação"""
def formatar_cpf(cpf: str) -> str:
"""Formata CPF: 123.456.789-00"""
cpf = ''.join(filter(str.isdigit, cpf))
if len(cpf) != 11:
return cpf
return f"{cpf[:3]}.{cpf[3:6]}.{cpf[6:9]}-{cpf[9:]}"
def formatar_telefone(telefone: str) -> str:
"""Formata telefone: (11) 99999-9999"""
tel = ''.join(filter(str.isdigit, telefone))
if len(tel) == 11:
return f"({tel[:2]}) {tel[2:7]}-{tel[7:]}"
elif len(tel) == 10:
return f"({tel[:2]}) {tel[2:6]}-{tel[6:]}"
return telefone
def formatar_moeda(valor: float, simbolo: str = "R$") -> str:
"""Formata valor como moeda brasileira"""
return f"{simbolo} {valor:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
# universo_utils/calculadora.py
"""Módulo de calculadora científica"""
import math
from typing import List, Union
Number = Union[int, float]
class Calculadora:
"""Calculadora científica completa"""
def __init__(self):
self.historico: List[str] = []
self.memoria: float = 0
def _registrar(self, operacao: str, resultado: Number):
"""Registra operação no histórico"""
self.historico.append(f"{operacao} = {resultado}")
# Operações básicas
def somar(self, a: Number, b: Number) -> Number:
resultado = a + b
self._registrar(f"{a} + {b}", resultado)
return resultado
def subtrair(self, a: Number, b: Number) -> Number:
resultado = a - b
self._registrar(f"{a} - {b}", resultado)
return resultado
def multiplicar(self, a: Number, b: Number) -> Number:
resultado = a * b
self._registrar(f"{a} × {b}", resultado)
return resultado
def dividir(self, a: Number, b: Number) -> float:
if b == 0:
raise ValueError("Divisão por zero!")
resultado = a / b
self._registrar(f"{a} ÷ {b}", resultado)
return resultado
# Operações científicas
def raiz_quadrada(self, n: Number) -> float:
if n < 0:
raise ValueError("Não existe raiz de número negativo!")
resultado = math.sqrt(n)
self._registrar(f"√{n}", resultado)
return resultado
def potencia(self, base: Number, exp: Number) -> Number:
resultado = math.pow(base, exp)
self._registrar(f"{base}^{exp}", resultado)
return resultado
def fatorial(self, n: int) -> int:
if n < 0:
raise ValueError("Fatorial não definido para negativos!")
resultado = math.factorial(n)
self._registrar(f"{n}!", resultado)
return resultado
# Memória
def memoria_adicionar(self, valor: Number):
self.memoria += valor
def memoria_limpar(self):
self.memoria = 0
def memoria_recuperar(self) -> float:
return self.memoria
# Histórico
def ver_historico(self) -> List[str]:
return self.historico.copy()
def limpar_historico(self):
self.historico.clear()
# examples/exemplo_uso.py
"""Exemplo de uso do pacote universo_utils"""
from universo_utils import (
ValidadorEmail,
ValidadorCPF,
ValidadorSenha,
formatar_cpf,
formatar_telefone,
formatar_moeda,
Calculadora
)
# === Validadores ===
print("=== VALIDADORES ===\n")
# Email
emails = ["[email protected]", "invalido@", "[email protected]"]
for email in emails:
valido = ValidadorEmail.validar(email)
status = "✅" if valido else "❌"
print(f"{status} {email}")
# CPF
cpfs = ["123.456.789-09", "111.111.111-11", "529.982.247-25"]
for cpf in cpfs:
valido = ValidadorCPF.validar(cpf)
status = "✅" if valido else "❌"
print(f"{status} CPF: {cpf}")
# Senha
senhas = ["123", "Senha@123", "abcdefgh"]
for senha in senhas:
resultado = ValidadorSenha.validar(senha)
status = "✅" if resultado["valida"] else "❌"
print(f"{status} Senha: {senha} (score: {resultado['score']}/5)")
# === Formatadores ===
print("\n=== FORMATADORES ===\n")
print(formatar_cpf("12345678900"))
print(formatar_telefone("11999998888"))
print(formatar_moeda(1234567.89))
# === Calculadora ===
print("\n=== CALCULADORA ===\n")
calc = Calculadora()
print(calc.somar(10, 5))
print(calc.multiplicar(4, 8))
print(calc.raiz_quadrada(144))
print(calc.potencia(2, 10))
print(calc.fatorial(5))
print("\nHistórico:")
for op in calc.ver_historico():
print(f" {op}")
🔧 __name__ e __main__
O padrão if __name__ == "__main__" permite que um módulo seja tanto importado quanto executado diretamente:
# meu_modulo.py
def funcao_util():
return "Resultado da função"
def main():
"""Código executado apenas quando rodado diretamente"""
print("Executando como script principal!")
print(funcao_util())
# Este bloco só executa se o arquivo for executado diretamente
# Não executa se for importado
if __name__ == "__main__":
main()
# Rodando diretamente:
# python meu_modulo.py
# Output: "Executando como script principal!"
# Importando:
# import meu_modulo
# (não executa o main automaticamente)
💡 Boas Práticas
- Imports no topo: Sempre coloque imports no início do arquivo
- Ordenação: Primeiro stdlib, depois terceiros, depois locais
- Imports explícitos: Evite
from x import * - Um módulo, uma responsabilidade: Mantenha módulos coesos
- Docstrings: Documente seus módulos e funções
- __all__: Defina o que será exportado
- Ambientes virtuais: Use venv para isolar dependências
# ✅ BOM - Imports organizados
import os
import sys
from datetime import datetime
import requests
import pandas as pd
from meu_pacote import funcao
from meu_pacote.utils import helper
# ❌ RUIM - Imports bagunçados
from meu_pacote import *
import pandas, numpy, requests
from datetime import *
🌐 Ambientes Virtuais
# Criar ambiente virtual
python -m venv venv
# Ativar (Windows)
venv\Scripts\activate
# Ativar (Linux/Mac)
source venv/bin/activate
# Instalar dependências
pip install -r requirements.txt
# Desativar
deactivate
🚀 Próximos Passos
Agora que você domina módulos e pacotes, explore:
- Funções - Base para criar módulos
- POO - Classes em módulos
- Arquivos - Módulos json, csv
- Try/Except - Tratamento em imports
- APIs com requests - Consumir serviços web
- Flask/Django - Frameworks web
- Pandas - Análise de dados
- Pytest - Testes automatizados
Quer dominar o ecossistema Python? Confira nosso curso completo com projetos usando bibliotecas profissionais!
📝 Resumo
- ✅ Módulos - arquivos .py reutilizáveis
- ✅ Import, from...import, alias
- ✅ Módulos nativos: math, random, datetime, os, json
- ✅ Pacotes - coleções de módulos com __init__.py
- ✅ Pip - gerenciador de pacotes
- ✅ Requirements.txt - dependências
- ✅ Projeto: Pacote universo_utils completo
- ✅ __name__ e __main__
- ✅ Ambientes virtuais (venv)
- ✅ Boas práticas de organização
Módulos e pacotes são fundamentais para qualquer projeto Python real. Domine esta organização e você estará pronto para criar aplicações profissionais e escaláveis!