🌗 ← Índice

🐍 Python P08 — Módulos e Pacotes


Data: 05/07/2026

Nível: Intermediário




Escrever tudo num arquivo só funciona até a página 2. Depois vira bagunça. Hoje tu vai aprender a organizar código de verdade: módulos, pacotes, imports, venv e pip.




🎯 O que vamos aprender


  • `import` — como Python encontra módulos
  • Criar teus próprios módulos
  • `__name__ == "__main__"` — o segredo mais mal-explicado do Python
  • Pacotes: pastas com `__init__.py`
  • `venv` — ambientes virtuais (finalmente!)
  • `pip` — instalar pacotes externos



  • 📦 O que é um módulo


    Módulo = arquivo .py. Qualquer arquivo Python é um módulo automaticamente.


    
    # math é um módulo built-in
    import math
    print(math.sqrt(25))  # 5.0
    

    Formas de importar


    
    # 1. Importa o módulo inteiro (acesso com math.xxx)
    import math
    print(math.pi)
    
    # 2. Importa funções específicas
    from math import sqrt, pi
    print(sqrt(16), pi)
    
    # 3. Importa tudo (PERIGOSO — polui namespace)
    from math import *
    print(sin(1))  # de onde veio isso?!
    
    # 4. Apelido
    import numpy as np
    import pandas as pd
    

    Regra de ouro: prefira import modulo ou from modulo import funcao. Evite *.




    🏗️ Criando teu próprio módulo


    Crie dois arquivos na mesma pasta:


    util.py (o módulo):

    
    def saudacao(nome):
        return f"Olá, {nome}!"
    
    def soma_tudo(*numeros):
        return sum(numeros)
    
    PI = 3.14159
    

    main.py (quem usa):

    
    import util
    
    print(util.saudacao("Hugo"))      # Olá, Hugo!
    print(util.soma_tudo(1, 2, 3))    # 6
    print(util.PI)                     # 3.14159
    



    🔑 `__name__ == "__main__"` — o mistério revelado


    Quando tu roda um arquivo diretamente (python main.py), a variável especial __name__ vale "__main__".


    Quando o mesmo arquivo é importado por outro, __name__ vale o nome do módulo.


    
    # util.py
    def saudacao(nome):
        return f"Olá, {nome}!"
    
    # Código que só roda se executado diretamente
    if __name__ == "__main__":
        # Teste rápido
        print(saudacao("Teste"))
    

    Agora:

  • `python util.py` → imprime "Olá, Teste!" (roda o bloco `if`)
  • `import util` em outro arquivo → **não** imprime nada (não roda o bloco)

  • Pra que serve: testar módulos sem atrapalhar quem importa eles.




    📁 Pacotes: pastas com `__init__.py`


    Quando o projeto cresce, organize em pastas:


    
    meu_projeto/
    ├── main.py
    └── utils/
        ├── __init__.py    # Torna "utils" um pacote
        ├── strings.py
        └── arquivos.py
    

    __init__.py pode estar vazio. A existência dele diz ao Python: "Esta pasta é um pacote, pode importar".


    
    # main.py
    from utils.strings import formatar_nome
    from utils.arquivos import ler_json
    
    nome = formatar_nome("hugo costa")
    dados = ler_json("config.json")
    

    Import relativo (dentro do pacote)


    
    # utils/arquivos.py
    from .strings import normalizar   # . = mesmo pacote
    



    🧪 `venv` — Ambiente Virtual (FINALMENTE!)


    Cada projeto tem dependências diferentes. venv isola elas:


    
    # Criar ambiente (só 1x)
    python3 -m venv .venv
    
    # Ativar (toda sessão nova)
    source .venv/bin/activate     # Linux/macOS
    .venv\Scripts\activate        # Windows
    
    # Instalar pacotes (isolados!)
    pip install requests pandas
    
    # Salvar dependências
    pip freeze > requirements.txt
    
    # Desativar
    deactivate
    

    Pra que serve:

  • Projeto A usa `pandas==2.0`, Projeto B usa `pandas==1.5` → sem conflito
  • Não polui o Python do sistema
  • `requirements.txt` permite recriar o ambiente em outra máquina



  • 📥 `pip` — Instalando pacotes


    
    # Instalar
    pip install requests
    pip install pandas==2.1.0     # Versão específica
    
    # Listar o que tem
    pip list
    
    # Ver detalhes
    pip show requests
    
    # Desinstalar
    pip uninstall requests
    
    # Instalar de requirements.txt
    pip install -r requirements.txt
    

    Pacotes essenciais pra ti


    PacotePra quê

    |---|---|

    `requests`Consumir APIs HTTP
    `python-dotenv`Variáveis de ambiente (.env)
    `pytest`Testes
    `rich`Terminal bonito
    `pandas`Dados tabulares
    `beautifulsoup4`Web scraping



    ✍️ Exercícios


    1. Cria teu módulo `calculadora.py`

    Com funções somar(a, b), subtrair(a, b), multiplicar(a, b), dividir(a, b). Usa __name__ == "__main__" pra testar.


    
    # calculadora.py — teu código aqui
    

    2. Importa e usa

    Cria um main.py que importa calculadora e usa as 4 funções com números de exemplo.


    
    # main.py — teu código aqui
    

    3. Cria um pacote

    Estrutura:

    
    meu_app/
    ├── main.py
    └── finanças/
        ├── __init__.py
        └── operacoes.py
    

    Em operacoes.py, cria calcular_juros(capital, taxa, meses). Em main.py, importa e calcula R$1000 a 5% por 12 meses.




    🧪 Desafio


    Cria um mini-projeto organizado:


    
    gerenciador/
    ├── main.py           # Entrada do programa
    ├── modelos/
    │   ├── __init__.py
    │   └── tarefa.py     # Classe Tarefa
    └── utils/
        ├── __init__.py
        └── arquivo.py    # Salvar/carregar JSON
    

    Requisitos:

    1. tarefa.py: classe Tarefa com titulo, concluida, __str__

    2. arquivo.py: salvar_tarefas(lista, caminho) e carregar_tarefas(caminho) usando json

    3. main.py: menu com opções (adicionar, listar, concluir, sair)


    
    # Implementa aí!
    



    ✅ Gabarito


    Exercício 1 — calculadora.py


    
    def somar(a, b):
        return a + b
    
    def subtrair(a, b):
        return a - b
    
    def multiplicar(a, b):
        return a * b
    
    def dividir(a, b):
        if b == 0:
            raise ValueError("Divisão por zero")
        return a / b
    
    if __name__ == "__main__":
        print("=== Testes ===")
        print(somar(2, 3))        # 5
        print(dividir(10, 2))     # 5.0
    


    Exercício 2 — main.py


    
    import calculadora
    
    print(calculadora.somar(10, 5))
    print(calculadora.subtrair(10, 5))
    print(calculadora.multiplicar(10, 5))
    print(calculadora.dividir(10, 5))
    


    Exercício 3 — Pacote finanças


    
    # finanças/operacoes.py
    def calcular_juros(capital, taxa, meses):
        return capital * (1 + taxa/100) ** meses
    
    # main.py
    from finanças.operacoes import calcular_juros
    
    montante = calcular_juros(1000, 5, 12)
    print(f"R$ {montante:.2f}")   # R$ 1795.86
    


    Desafio — Gerenciador de Tarefas


    
    # modelos/tarefa.py
    class Tarefa:
        def __init__(self, titulo, concluida=False):
            self.titulo = titulo
            self.concluida = concluida
        
        def __str__(self):
            status = "✓" if self.concluida else "☐"
            return f"[{status}] {self.titulo}"
        
        def to_dict(self):
            return {"titulo": self.titulo, "concluida": self.concluida}
        
        @classmethod
        def from_dict(cls, d):
            return cls(d["titulo"], d["concluida"])
    
    # utils/arquivo.py
    import json
    
    def salvar_tarefas(tarefas, caminho="tarefas.json"):
        with open(caminho, "w") as f:
            json.dump([t.to_dict() for t in tarefas], f, indent=2)
    
    def carregar_tarefas(caminho="tarefas.json"):
        try:
            with open(caminho) as f:
                return [Tarefa.from_dict(d) for d in json.load(f)]
        except FileNotFoundError:
            return []
    
    # main.py
    from modelos.tarefa import Tarefa
    from utils.arquivo import salvar_tarefas, carregar_tarefas
    
    tarefas = carregar_tarefas()
    
    while True:
        print("\n=== Gerenciador ===")
        print("1. Adicionar")
        print("2. Listar")
        print("3. Concluir")
        print("4. Sair")
        op = input("> ")
        
        if op == "1":
            titulo = input("Título: ")
            tarefas.append(Tarefa(titulo))
        elif op == "2":
            for i, t in enumerate(tarefas):
                print(f"{i}: {t}")
        elif op == "3":
            idx = int(input("Nº da tarefa: "))
            tarefas[idx].concluida = True
        elif op == "4":
            salvar_tarefas(tarefas)
            print("Salvo. Falou!")
            break
    




    **Próxima aula:** P09 — Strings, formatação e regex