Importando entre diretórios diferentes
Quando um projeto cresce, é comum dividir o código em pacotes organizados por responsabilidade. Suponha a seguinte estrutura:
aplicacao/
├── principal.py
└── pacotes/
├── utilitarios/
│ ├── __init__.py
│ └── texto.py
└── modelos/
├── __init__.py
└── dados.py
Se principal.py precisar usar o módulo texto.py, o importe absoluto funciona normalmente:
# principal.py
from pacotes.utilitarios import texto
texto.exibir_mensagem()
Entretanto, quando um módulo dentro de um subpacote precisa acessar outro subpacote paralelo, o importe pode falhar. Por exemplo, se dados.py tentar importar utilitarios.texto diretamente:
# pacotes/modelos/dados.py
from pacotes.utilitarios import texto
Ao executar dados.py, o Python pode gerar um erro informando que não encontra pacotes. Isso acontece porque o diretório raiz do projeto não está no sys.path. Uma solução prática é adicionar o caminho raiz dinamicamente:
# pacotes/modelos/dados.py
import sys
from pathlib import Path
raiz = Path(__file__).resolve().parent.parent.parent
sys.path.insert(0, str(raiz))
from pacotes.utilitarios import texto
def executar():
texto.exibir_mensagem()
if __name__ == "__main__":
executar()
Com a raiz inserida em sys.path, o Python consegue resolver o pacote corretamente. Essa abordagem funciona mesmo quando os módulos estão em unidades de disco distintas, desde que o caminho seja informado corretamente. Para evitar problemas com barras invertidas no Windows, prefira usar pathlib ao invés de concatenar strings manualmente.
Importando módulos de um mesmo pacote
Um pacote Python é simplesmente um diretório que contém um arquivo __init__.py. Esse arquivo pode estar vazio ou conter inicializações comuns. Veja o exemplo:
minipacote/
__init__.py
arq1.py
arq2.py
teste.py
Conteúdo dos arquivos:
# minipacote/__init__.py
print("minipacote foi inicializado")
# minipacote/arq1.py
def exibir():
print("Função do arquivo arq1")
# minipacote/arq2.py
def mostrar():
print("Função do arquivo arq2")
# teste.py
from minipacote.arq1 import exibir
from minipacote.arq2 import mostrar
exibir()
mostrar()
Resultado esperado:
minipacote foi inicializado
Função do arquivo arq1
Função do arquivo arq2
O arquivo __init__.py é executado apenas uma vez, na primeira vez que o pacote é importado. Ele é útil para centralizar configurações e expor funcionalidades que devem estar disponíveis quando o pacote for utilizado.