
Passo 1 de 6
Criar uma hierarquia de pacotes regulares
Organize módulos de relatórios em um pacote regular e um subpacote, usando arquivos init.py para definir a estrutura.
Trilha de aprendizado · Nível 5 · Tutorial 3
Organizar módulos relacionados em uma hierarquia de pacotes locais e executá-los preservando a resolução correta das importações.
Criar uma hierarquia de pacotes regulares
Organize módulos de relatórios em um pacote regular e um subpacote, usando arquivos __init__.py para definir a estrutura. 3 min
Importar usando o nome completo do pacote
Transforme posições na hierarquia de arquivos em nomes qualificados e use importações absolutas explícitas no pacote relatorios. 3 min
Executar um módulo a partir da pasta correta
Execute o módulo principal pelo nome qualificado com -m e reconheça como a pasta de partida determina a localização do pacote. 3 min
Usar importações relativas dentro do pacote
Referencie módulos próximos com pontos explícitos e execute o programa preservando o contexto do pacote. 3 min
Reorganizar dependências para evitar ciclos
Identifique um ciclo entre módulos, extraia configurações compartilhadas e preserve o resultado do projeto com dependências unidirecionais. 4 min
Concluir e verificar o pacote local
Integre um novo resumo de média, confira a direção das dependências e execute o pacote completo no contexto correto. 5 min

Passo 1 de 6
Organize módulos de relatórios em um pacote regular e um subpacote, usando arquivos init.py para definir a estrutura.
Você organizará um projeto chamado projeto_relatorios. Dentro dele, o pacote de topo relatorios reunirá dados e a coordenação do programa. O subpacote resumos concentrará as responsabilidades de cálculo e formatação:
dados.py: mantém os dados de vendas em memória.principal.py: será o ponto de coordenação do programa.resumos/calculos.py: realiza os cálculos.resumos/formatacao.py: produz o texto do resumo.A pasta do projeto contém o pacote, enquanto as pastas de pacote contêm módulos ou outros pacotes.
A estrutura possui quatro níveis distintos: pasta do projeto, pacote de topo, subpacote e arquivos de módulos.

projeto_relatorios contém o pacote relatorios; dentro dele, resumos é outro pacote.
No seu editor, crie exatamente esta estrutura:
projeto_relatorios/
└── relatorios/
├── __init__.py
├── dados.py
├── principal.py
└── resumos/
├── __init__.py
├── calculos.py
└── formatacao.pyCrie os dois arquivos __init__.py e deixe-os completamente vazios. Eles identificam relatorios e resumos como pacotes regulares. A pasta externa projeto_relatorios é apenas a pasta do projeto e não precisa desse arquivo.
Na primeira importação de um pacote em um processo, o Python executa o respectivo __init__.py. Isso também acontece quando a solicitação inicial é por um submódulo: os pacotes necessários para alcançá-lo são inicializados.
Um __init__.py vazio é suficiente para esta estrutura. Sua execução não produz efeito visível e não importa automaticamente todos os outros módulos da pasta.
Dica
Não use __init__.py como uma lista central de módulos. Neste projeto, mantenha os dois arquivos vazios e coloque cada responsabilidade em seu módulo próprio.
Este módulo mantém os dados de exemplo usados ao longo do projeto.
VENDAS = [1200.0, 850.0, 1530.0, 990.0]
As operações numéricas ficam no subpacote de resumos.
def calcular_total(valores):
return sum(valores)
def calcular_media(valores):
if not valores:
return 0.0
return calcular_total(valores) / len(valores)
Esta primeira versão já produz o resumo na convenção monetária que será preservada. No próximo step, o cálculo existente será conectado a ela por uma importação explícita.
def criar_resumo(valores):
total = sum(valores)
return f"Total de vendas: R$ {total:.2f}"
Por enquanto, o módulo principal contém somente a estrutura de coordenação já conhecida. As conexões entre os módulos serão acrescentadas no próximo step.
def main():
pass
if __name__ == "__main__":
main()
Relacione cada elemento da árvore ao seu papel no projeto.
Toque em um item e depois no par correspondente.

Passo 2 de 6
Transforme posições na hierarquia de arquivos em nomes qualificados e use importações absolutas explícitas no pacote relatorios.
Na hierarquia criada, cada módulo pode ser identificado por um nome qualificado. Ele reúne pacote, subpacote e módulo, separados por pontos.
Por exemplo, o arquivo relatorios/resumos/calculos.py corresponde ao nome importável relatorios.resumos.calculos.
No nome qualificado, retire a extensão .py e troque os separadores de pasta por pontos.
Observe como cada nível da árvore participa do nome qualificado do módulo.

Pacote, subpacote e módulo formam o nome qualificado relatorios.resumos.calculos.
Dica
Uma importação absoluta começa pelo pacote de topo, como relatorios. Ela não começa por um caminho do sistema, como C:\projetos ou /home/usuario/projetos.
Com import relatorios.dados, o acesso mantém o nome qualificado: relatorios.dados.VENDAS.
Com from relatorios.resumos.calculos import calcular_total, a função é vinculada diretamente ao nome calcular_total. Portanto, a chamada não repete o caminho do módulo.
Exemplo
import relatorios.dados
from relatorios.resumos.calculos import calcular_total
valores = relatorios.dados.VENDAS
total = calcular_total(valores)A primeira forma preserva a origem no uso de VENDAS. A segunda permite chamar diretamente a função importada.
Mantenha os demais arquivos criados anteriormente e substitua o conteúdo dos dois arquivos abaixo. Todas as importações começam pelo pacote de topo relatorios.
Este módulo usa a função de cálculo pelo nome qualificado completo de sua origem.
from relatorios.resumos.calculos import calcular_total
def criar_resumo(valores):
total = calcular_total(valores)
return f"Total de vendas: R$ {total:.2f}"
O módulo principal importa o módulo dados inteiro e uma função específica de formatacao.
import relatorios.dados
from relatorios.resumos.formatacao import criar_resumo
def main():
resumo = criar_resumo(relatorios.dados.VENDAS)
print(resumo)
if __name__ == "__main__":
main()
Complete a importação absoluta:
from ____ import calcular_total
Depois de import relatorios.dados, complete a expressão que obtém a constante:
valores = ____

Passo 3 de 6
Execute o módulo principal pelo nome qualificado com -m e reconheça como a pasta de partida determina a localização do pacote.
Os arquivos permanecem como ficaram no step anterior. Para executar o programa, abra o terminal em projeto_relatorios, a pasta que contém o pacote de topo relatorios.
Use -m para pedir ao Python que localize e execute um módulo por seu nome qualificado. Portanto, o argumento é relatorios.principal: sem .py e sem separadores de pasta.
Estar dentro de relatorios não equivale a estar na pasta do projeto. Nesse caso, o Python procuraria outro pacote relatorios a partir do local inadequado.

O comando parte de projeto_relatorios, que contém o pacote relatorios; o módulo é localizado pelo nome relatorios.principal.
Com o terminal aberto em projeto_relatorios, execute o comando abaixo. Se o comando de Python 3 no seu computador for python3, py ou outro, substitua apenas python; preserve -m relatorios.principal.
A opção -m localiza o módulo como parte da hierarquia de pacotes. Isso é diferente de fornecer ao interpretador um caminho de arquivo, como relatorios/principal.py.
Execute somente esta linha no terminal:
python -m relatorios.principalCompare a saída produzida com esta linha:
Total de vendas: R$ 4570.00Atenção
Se o terminal estiver dentro da pasta relatorios, o mesmo comando poderá falhar com uma mensagem como No module named 'relatorios'. Volte para projeto_relatorios e repita o comando. Não altere o caminho de busca do Python para contornar o problema.
Qual combinação executa o módulo principal deste projeto local?
Primeiro, entre na pasta relatorios e tente executar python -m relatorios.principal. Observe a falha de localização. Depois, volte para projeto_relatorios, repita o mesmo comando e compare o resultado com a saída esperada.
Se necessário, adapte somente o comando usado para iniciar o Python 3 no seu computador.
Em qual pasta o primeiro comando foi executado, que falha de localização você observou e como corrigiu o ponto de partida? Registre também o comando bem-sucedido e a saída produzida.
Escreva pelo menos 80 caracteres (0/80).

Passo 4 de 6
Referencie módulos próximos com pontos explícitos e execute o programa preservando o contexto do pacote.
Uma importação relativa começa com pontos e é resolvida a partir do pacote ao qual o módulo pertence:
relatorios/principal.py, from .dados import VENDAS parte de relatorios. Um ponto representa esse pacote atual.relatorios/resumos/formatacao.py, from .calculos import calcular_total parte de relatorios.resumos.formatacao.py, from ..dados import VENDAS usaria dois pontos para subir ao pacote pai, relatorios, e então localizar dados.O último exemplo apenas demonstra o significado de ..; não o adicione ao projeto, pois a formatação não precisa importar os dados.
O módulo formatacao.py pertence ao subpacote relatorios.resumos. Por isso, um ponto mantém a busca nesse subpacote, enquanto dois pontos levam ao pacote pai relatorios.

Os pontos são interpretados pela posição do módulo na hierarquia, não pela pasta atual do terminal.
Substitua integralmente os dois arquivos abaixo. As novas importações apontam para os mesmos recursos das formas absolutas usadas anteriormente. A escolha é de clareza: nomes absolutos deixam a origem completa visível; nomes relativos podem destacar relações internas próximas. Nenhuma das duas formas precisa ser usada em todos os casos.
Aqui, .calculos e relatorios.resumos.calculos apontam para o mesmo módulo.
from .calculos import calcular_total
def criar_resumo(valores):
total = calcular_total(valores)
return f"Total de vendas: R$ {total:.2f}"
Como principal.py pertence a relatorios, .dados e .resumos partem desse pacote.
from .dados import VENDAS
from .resumos.formatacao import criar_resumo
def main():
resumo = criar_resumo(VENDAS)
print(resumo)
if __name__ == "__main__":
main()
Com o terminal aberto em projeto_relatorios, teste primeiro a execução direta abaixo. Embora o caminho encontre o arquivo, essa forma inicia principal.py como um script isolado e não fornece automaticamente o contexto necessário para resolver .dados e .resumos.
Execute esta linha no terminal usando o comando de Python 3 configurado no seu computador.
python relatorios/principal.pyAtenção
A execução direta deve falhar com uma mensagem semelhante a ImportError: attempted relative import with no known parent package. Não altere sys.path nem as importações para contornar isso. Permaneça em projeto_relatorios e execute o módulo pelo nome qualificado com -m.
Este comando fornece o contexto de relatorios e deve produzir Total de vendas: R$ 4570.00.
python -m relatorios.principalAssocie cada importação relativa à forma absoluta equivalente.
Toque em um item e depois no par correspondente.
Por que python relatorios/principal.py falha com as importações relativas, enquanto python -m relatorios.principal funciona quando executado em projeto_relatorios?
Escreva pelo menos 80 caracteres (0/80).

Passo 5 de 6
Identifique um ciclo entre módulos, extraia configurações compartilhadas e preserve o resultado do projeto com dependências unidirecionais.
Em um diagrama de dependências, A → B significa que A importa B. Uma sequência que retorna ao ponto inicial forma um ciclo.
Considere uma tentativa de compartilhar a política de precisão dos relatórios. formatacao.py precisa dos cálculos, mas calculos.py tenta obter CASAS_DECIMAIS de formatacao.py. Assim, surge o ciclo:
formatacao → calculos → formatacao
Ao importar formatacao, o Python começa a executá-lo e encontra a importação de calculos. Durante a inicialização de calculos, a importação tenta acessar CASAS_DECIMAIS em um formatacao ainda parcialmente inicializado. Como esse nome ainda não foi definido, a importação pode falhar.
As duas setas entre os módulos revelam o caminho circular.

A seta parte do módulo que realiza a importação. O retorno ao módulo inicial caracteriza o ciclo.
Analise esta versão completa, mas não a copie para o projeto. A política de precisão é buscada no módulo de formatação.
from .formatacao import CASAS_DECIMAIS
def calcular_total(valores):
return round(sum(valores), CASAS_DECIMAIS)
def calcular_media(valores):
if not valores:
return 0.0
return round(
calcular_total(valores) / len(valores),
CASAS_DECIMAIS,
)
A primeira instrução inicia calculos.py antes que as configurações abaixo tenham sido definidas.
from .calculos import calcular_total
SIMBOLO_MOEDA = "R$"
CASAS_DECIMAIS = 2
def criar_resumo(valores):
total = calcular_total(valores)
return (
f"Total de vendas: {SIMBOLO_MOEDA} "
f"{total:.{CASAS_DECIMAIS}f}"
)
Escolha a organização em que formatacao.py usa os cálculos, enquanto a política compartilhada fica em um módulo de responsabilidade específica.
Crie constantes.py no subpacote relatorios/resumos e substitua integralmente calculos.py e formatacao.py pelas versões abaixo.
CASAS_DECIMAIS representa a política de precisão dos resultados do relatório, usada no cálculo e na apresentação. SIMBOLO_MOEDA também pertence às configurações desse relatório. Assim, constantes.py tem uma responsabilidade específica, em vez de ser um depósito genérico.
Neste exercício, corrigiremos a direção das dependências por extração. Mantenha os arquivos __init__.py vazios: eles não devem centralizar essas importações.
As configurações compartilhadas passam a ter uma origem independente.
SIMBOLO_MOEDA = "R$"
CASAS_DECIMAIS = 2
O módulo de cálculos consulta diretamente a política de precisão.
from .constantes import CASAS_DECIMAIS
def calcular_total(valores):
return round(sum(valores), CASAS_DECIMAIS)
def calcular_media(valores):
if not valores:
return 0.0
return round(
calcular_total(valores) / len(valores),
CASAS_DECIMAIS,
)
A apresentação depende do cálculo e das configurações, sem receber nenhuma importação de volta.
from .calculos import calcular_total
from .constantes import CASAS_DECIMAIS, SIMBOLO_MOEDA
def criar_resumo(valores):
total = calcular_total(valores)
return (
f"Total de vendas: {SIMBOLO_MOEDA} "
f"{total:.{CASAS_DECIMAIS}f}"
)
Mantenha principal.py, dados.py e os arquivos __init__.py como estavam. Abra o terminal em projeto_relatorios, a pasta que contém o pacote relatorios, e execute o módulo principal.
python -m relatorios.principal
Compare manualmente a linha produzida. A reorganização das dependências não deve alterar o resultado.
Total de vendas: R$ 4570.00
Qual foi a saída da execução? Explique por que as dependências formatacao → calculos, formatacao → constantes e calculos → constantes não formam um ciclo.
Escreva pelo menos 80 caracteres (0/80).

Passo 6 de 6
Integre um novo resumo de média, confira a direção das dependências e execute o pacote completo no contexto correto.
Você acrescentará media.py ao subpacote relatorios/resumos. O novo módulo apresentará a média das vendas reutilizando calcular_media e as configurações de constantes.py.
A estrutura final será:
projeto_relatorios/
└── relatorios/
├── __init__.py
├── dados.py
├── principal.py
└── resumos/
├── __init__.py
├── calculos.py
├── constantes.py
├── formatacao.py
└── media.pyMantenha os dois arquivos __init__.py vazios. As dependências devem seguir em uma única direção: os módulos de apresentação podem importar cálculos e constantes, mas estes não devem importar os módulos de apresentação.
As setas indicam quem importa quem. Nenhuma sequência retorna ao módulo de origem.

principal coordena o programa; formatacao e media reutilizam módulos de nível mais básico, sem receber importações de volta.
Crie media.py com importações relativas, pois seus recursos estão no mesmo subpacote. Depois, substitua principal.py pela versão completa abaixo, que usa importações absolutas iniciadas por relatorios. Preserve os demais arquivos exatamente como ficaram no step anterior.
O módulo recebe os dados, calcula a média e produz a segunda linha do relatório.
from .calculos import calcular_media
from .constantes import CASAS_DECIMAIS, SIMBOLO_MOEDA
def criar_resumo_media(valores):
media = calcular_media(valores)
return (
f"Média de vendas: {SIMBOLO_MOEDA} "
f"{media:.{CASAS_DECIMAIS}f}"
)
O módulo coordenador usa os dados existentes e apresenta os dois resumos.
from relatorios.dados import VENDAS
from relatorios.resumos.formatacao import criar_resumo
from relatorios.resumos.media import criar_resumo_media
def main():
print(criar_resumo(VENDAS))
print(criar_resumo_media(VENDAS))
if __name__ == "__main__":
main()
Abra o terminal em projeto_relatorios, a pasta que contém o pacote relatorios. Execute o módulo principal pelo nome qualificado. Se o comando do Python 3 no seu computador for diferente, substitua somente python.
Execute esta linha no terminal.
python -m relatorios.principal
Compare manualmente as duas linhas produzidas pelo programa.
Total de vendas: R$ 4570.00
Média de vendas: R$ 1142.50
Informe onde você criou o novo módulo, quais importações relativas e absolutas foram usadas, de qual pasta executou o programa, qual comando utilizou e qual saída observou. Por fim, explique por que as dependências finais não formam um ciclo.
Escreva pelo menos 120 caracteres (0/120).
Resumo
Use estes pontos para revisar o projeto concluído.
__init__.py.relatorios e usa -m relatorios.principal.Parabéns! Você concluiu: Organizar módulos em pacotes locais
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks