Programador Leigo
Python 12 min leitura 15 MAR 2026

Como organizar código Python: imports, módulos e boas práticas

Saia do 'tudo num arquivo só' e aprenda a organizar seu código Python com módulos, imports e boas práticas de escrita.


O problema do arquivo gigante

No começo, é normal colocar tudo num arquivo só. Mas conforme o projeto cresce, isso vira um pesadelo:

# app.py - 800 linhas, tudo misturado
def conectar_banco():
    ...

def validar_email():
    ...

def calcular_frete():
    ...

def enviar_notificacao():
    ...

# mais 50 funcoes aqui...

Você não encontra nada, funções não relacionadas ficam juntas e qualquer mudança vira um risco. A solução é separar em módulos.


Módulos: cada arquivo é um módulo

Em Python, qualquer arquivo .py é um módulo. Você pode importar funções de um arquivo em outro:

meu_projeto/
  app.py
  validacao.py
  banco.py
# validacao.py
def email_valido(email):
    return "@" in email and "." in email

def cpf_valido(cpf):
    return len(cpf) == 11 and cpf.isdigit()
# app.py
from validacao import email_valido, cpf_valido

email = input("Email: ")
if email_valido(email):
    print("Email valido!")

Cada arquivo tem uma responsabilidade clara. Se precisar mexer na validação, você sabe exatamente onde ir.


Formas de importar

import simples

import validacao

validacao.email_valido("teste@email.com")

Usa o nome do módulo como prefixo. Bom para evitar conflitos de nomes.

from ... import

from validacao import email_valido

email_valido("teste@email.com")

Importa direto, sem prefixo. Mais prático quando você usa poucas funções.

import com apelido

import validacao as val

val.email_valido("teste@email.com")

Útil quando o nome do módulo é longo.

Evite import com asterisco

from validacao import *   # NAO faca isso

Importa tudo de uma vez. Parece conveniente, mas você perde o controle sobre o que está usando e pode sobrescrever funções sem perceber.


Pacotes: organizando em pastas

Quando o projeto cresce, agrupe módulos em pastas. Uma pasta com um arquivo __init__.py (pode estar vazio) é um pacote:

meu_projeto/
  app.py
  utils/
    __init__.py
    validacao.py
    formatacao.py
  banco/
    __init__.py
    conexao.py
    consultas.py
# app.py
from utils.validacao import email_valido
from banco.conexao import conectar

Cada pasta agrupa módulos relacionados. A estrutura do projeto já conta a história do que ele faz.


O que é __name__ == "__main__"

Você vai encontrar isso em muitos projetos Python:

# calculadora.py
def somar(a, b):
    return a + b

def subtrair(a, b):
    return a - b

if __name__ == "__main__":
    print(somar(10, 5))
    print(subtrair(10, 5))

Como funciona

Quando você roda python calculadora.py direto, o Python define __name__ como "__main__". O bloco if executa.

Quando outro arquivo importa esse módulo, __name__ é "calculadora". O bloco if não executa.

# app.py
from calculadora import somar

print(somar(3, 7))   # funciona, sem executar os prints do if

Use isso para separar o código que define funções do código que as testa. É uma boa prática em qualquer módulo.


Nomeação: a PEP 8

A PEP 8 é o guia de estilo oficial do Python. Você não precisa decorar tudo, mas essas regras são essenciais:

Variáveis e funções: snake_case

# Certo
nome_completo = "Maria Silva"
def calcular_total(itens):
    ...

# Errado
NomeCompleto = "Maria Silva"
def CalcularTotal(itens):
    ...

Classes: PascalCase

# Certo
class ContaBancaria:
    ...

# Errado
class conta_bancaria:
    ...

Constantes: MAIUSCULAS_COM_UNDERSCORE

# Certo
TAXA_JUROS = 0.05
MAX_TENTATIVAS = 3

# Errado
taxa_juros = 0.05

Nomes significativos

# Ruim - o que e x, y, d?
def calc(x, y, d):
    return x * y * (1 - d)

# Bom - qualquer pessoa entende
def calcular_preco(quantidade, preco_unitario, desconto):
    return quantidade * preco_unitario * (1 - desconto)

O nome deve dizer o que a coisa é ou faz, sem precisar de comentário.


Funções pequenas e focadas

Cada função deve fazer uma coisa e fazer bem:

# Ruim - faz tudo junto
def processar_pedido(pedido):
    # valida
    if not pedido["email"]:
        return "Email obrigatorio"
    if pedido["total"] <= 0:
        return "Total invalido"
    # calcula
    subtotal = sum(item["preco"] for item in pedido["itens"])
    frete = 15.0 if subtotal < 100 else 0
    total = subtotal + frete
    # salva no banco
    db.insert({"pedido": pedido, "total": total})
    # envia email
    enviar_email(pedido["email"], f"Pedido confirmado: R$ {total}")
    return "OK"
# Bom - cada funcao com sua responsabilidade
def validar_pedido(pedido):
    if not pedido["email"]:
        raise ValueError("Email obrigatorio")
    if pedido["total"] <= 0:
        raise ValueError("Total invalido")

def calcular_total(itens):
    subtotal = sum(item["preco"] for item in itens)
    frete = 15.0 if subtotal < 100 else 0
    return subtotal + frete

def processar_pedido(pedido):
    validar_pedido(pedido)
    total = calcular_total(pedido["itens"])
    db.insert({"pedido": pedido, "total": total})
    enviar_email(pedido["email"], f"Pedido confirmado: R$ {total}")

Funções menores são mais fáceis de entender, testar e reutilizar.


Comentários: menos é mais

Comentários bons explicam o porquê

# Timeout maior porque a API do banco e lenta nos horarios de pico
resposta = requests.get(url, timeout=30)

# Ignora o primeiro elemento que e sempre o cabecalho
dados = linhas[1:]

Comentários ruins explicam o óbvio

# Incrementa o contador
contador += 1

# Retorna o nome
return nome

# Cria uma lista vazia
itens = []

Se o código está tão confuso que precisa de comentário para cada linha, o problema não é a falta de comentário — é o código.

Código legível > comentário

# Com comentario para compensar nome ruim
x = 0.05  # taxa de juros

# Sem comentario, nome auto-explicativo
taxa_juros = 0.05

Estrutura de um projeto real

Para projetos pequenos a médios, essa estrutura funciona bem:

meu_projeto/
  app.py              ← ponto de entrada
  config.py           ← configuracoes (constantes, variaveis de ambiente)
  models/
    __init__.py
    usuario.py        ← logica de usuario
    produto.py        ← logica de produto
  utils/
    __init__.py
    validacao.py      ← funcoes de validacao
    formatacao.py     ← funcoes de formatacao
  requirements.txt    ← dependencias
  .gitignore          ← arquivos ignorados pelo Git
  .env                ← variaveis de ambiente (nunca vai pro Git)

Dicas para organizar

Regra Exemplo
Agrupe por funcionalidade models/, utils/, routes/
Um módulo = uma responsabilidade validacao.py só valida
Configurações separadas config.py com constantes e variáveis de ambiente
Ponto de entrada claro app.py ou main.py na raiz
Segredos fora do código .env para tokens e senhas

Ordem dos imports

A PEP 8 recomenda organizar os imports em três grupos, separados por uma linha em branco:

# 1. Biblioteca padrao do Python
import os
import json
from datetime import datetime

# 2. Bibliotecas externas (instaladas com pip)
import requests
from flask import Flask

# 3. Modulos do seu projeto
from utils.validacao import email_valido
from models.usuario import criar_usuario

Manter essa ordem facilita saber de onde cada coisa vem.


Resumo

Conceito Regra
Módulos Cada arquivo .py é um módulo
Pacotes Pasta com __init__.py
Imports Prefira from ... import específico
__name__ Use para separar definições de execução
Nomeação snake_case para variáveis/funções, PascalCase para classes
Funções Pequenas, focadas, uma responsabilidade
Comentários Explique o porquê, não o quê
Estrutura Agrupe por funcionalidade, configure separado

Organizar código não é frescura — é o que separa um script de estudante de um projeto profissional. Comece aplicando essas práticas agora e seu código vai ser mais fácil de ler, manter e evoluir.

Continue lendo

Compartilhar