🌗 ← Índice
Data: 14/08/2026
Nível: Intermediário-Avançado (Mês 3 — Projetos Reais)
| Regra | Exemplo |
|---|---|
| 4 espaços por indentação | `def funcao():` + 4 espaços |
| Máx 79/99 caracteres por linha | quebre com parênteses |
| Nomes: `snake_case` (funções/var), `CamelCase` (classes), `UPPER_CASE` (constantes) | `def calcular_total()`, `class Cliente`, `MAX_TENTATIVAS = 3` |
| 2 linhas em branco entre funções de topo; 1 entre métodos | — |
| Espaços ao redor de operadores | `a = b + c` (não `a=b+c`) |
| Importações: uma por linha, ordenadas | `import os` + `from pathlib import Path` |
# Ferramentas para verificar:
pip install black ruff
black meu_script.py # formata automaticamente
ruff check meu_script.py # aponta problemas
def calcular_total(preco: float, quantidade: int, desconto: float = 0.0) -> float:
"""Calcula o total com desconto."""
return preco * quantidade * (1 - desconto)
def buscar(nome: str) -> dict | None: # Python 3.10+ (ou Optional[dict])
...
def processar(itens: list[str]) -> list[int]:
...
| Situação | Anotação | |
|---|---|---|
| Pode ser nulo | `str \ | None` ou `Optional[str]` |
| Lista de X | `list[X]` | |
| Dict | `dict[str, int]` | |
| Tupla | `tuple[int, int]` | |
| Qualquer | `Any` (evite) |
def enviar_email(destino: str, assunto: str, corpo: str) -> bool:
"""Envia um e-mail.
Args:
destino: endereço do destinatário.
assunto: título do e-mail.
corpo: conteúdo em texto puro.
Returns:
True se enviado com sucesso, False caso contrário.
Raises:
ValueError: se o destino for inválido.
"""
if "@" not in destino:
raise ValueError(f"E-mail inválido: {destino}")
...
💡 Docstrings de módulo/classes/funções públicas = documentação automática (pydoc, Sphinx).
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
)
logger = logging.getLogger(__name__)
logger.debug("Detalhe de depuração") # só com level=DEBUG
logger.info("Processo iniciado")
logger.warning("Valor incomum detectado")
logger.error("Falha ao conectar")
logger.critical("Sistema parando")
2026-08-14 15:30:00 | INFO | __main__ | Processo iniciado
💡 Use `logger` no lugar de `print` em aplicações reais: níveis, timestamps, filtros e saída em arquivo.
import logging
logging.basicConfig(
level=logging.INFO,
filename="app.log",
format="%(asctime)s | %(levelname)s | %(message)s",
)
projeto/
├── main.py # CLI/ponto de entrada (fino)
├── servicos/
│ ├── __init__.py
│ ├── api.py # acesso a APIs
│ └── banco.py # banco de dados
├── modelos.py # classes de dados
├── utils.py # helpers
├── tests/
│ └── test_api.py
├── requirements.txt
└── .env
Regra prática: main.py só orquestra; a lógica fica em módulos importáveis (e testáveis).
Refatore o alerta_disco.py (Aula P24) com boas práticas:
"""Alerta de disco da VPS via Telegram."""
import logging
import os
import shutil
from dotenv import load_dotenv
import requests
load_dotenv()
TOKEN = os.getenv("TELEGRAM_TOKEN")
CHAT_ID = int(os.getenv("TELEGRAM_CHAT_ID", "0"))
LIMITE_PERCENTUAL = float(os.getenv("LIMITE_DISCO", "80"))
logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(message)s")
logger = logging.getLogger(__name__)
def uso_disco(caminho: str = "/") -> float:
"""Retorna o percentual de uso do disco.
Args:
caminho: ponto de montagem a verificar.
Returns:
Percentual de uso (0 a 100).
"""
uso = shutil.disk_usage(caminho)
return uso.used / uso.total * 100
def enviar_telegram(texto: str) -> bool:
"""Envia mensagem via bot do Telegram."""
try:
resposta = requests.post(
f"https://api.telegram.org/bot{TOKEN}/sendMessage",
json={"chat_id": CHAT_ID, "text": texto, "parse_mode": "Markdown"},
timeout=10,
)
return resposta.status_code == 200
except requests.exceptions.RequestException as erro:
logger.error("Falha ao enviar Telegram: %s", erro)
return False
def main() -> None:
"""Executa a verificação e envia o alerta se necessário."""
percentual = uso_disco()
logger.info("Disco: %.1f%% usado", percentual)
mensagem = f"💾 *Disco da VPS:* {percentual:.1f}% usado"
if percentual >= LIMITE_PERCENTUAL:
mensagem += f"\n\n⚠️ *ATENÇÃO:* limite de {LIMITE_PERCENTUAL:.0f}% excedido!"
if enviar_telegram(mensagem):
logger.info("Mensagem enviada")
else:
logger.error("Mensagem NÃO enviada")
if __name__ == "__main__":
main()
💡 Resultado: código pronto para produção — tipado, documentado, com logging e modular.
HB Estudos · ← Voltar ao índice de Python