As melhores práticas do Python em 2026 combinam os recursos em evolução da linguagem com princípios de engenharia de software testados em batalha. Este guia cobre a qualidade do código, a estrutura do projeto, os testes, o desempenho e o moderno conjunto de ferramentas usado no desenvolvimento profissional em Python.
📋 Table of Contents
Estilo e formatação de código
# Modern Python toolchain (2026)
pip install ruff # fastest linter + formatter (replaces black + flake8 + isort)
# Format all Python files
ruff format .
# Lint and auto-fix
ruff check . --fix
# pyproject.toml configuration
# [tool.ruff]
# line-length = 100
# select = ["E", "F", "I", "N", "UP"] # rules to enable
# ignore = ["E501"]
# GOOD: meaningful names, type hints, docstrings
def calculate_compound_interest(
principal: float,
annual_rate: float,
years: int,
compounds_per_year: int = 12,
) -> float:
# FV = P * (1 + r/n)^(n*t)
rate_per_period = annual_rate / compounds_per_year
periods = compounds_per_year * years
return principal * (1 + rate_per_period) ** periods
# BAD: cryptic names, no types, magic numbers
def calc(p, r, y, n=12):
return p * (1 + r/n) ** (n*y)
Estrutura do Projeto
myapp/
pyproject.toml # project metadata + tool config
README.md
src/
myapp/
__init__.py
main.py # entry point
api/ # FastAPI routes
__init__.py
users.py
posts.py
models/ # SQLAlchemy/Pydantic models
user.py
post.py
services/ # business logic
user_service.py
repositories/ # database access
user_repo.py
core/ # config, dependencies
config.py
database.py
tests/
unit/
test_user_service.py
integration/
test_api.py
conftest.py # shared fixtures
Gerenciamento de configuração
# core/config.py — Pydantic Settings
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=False,
)
# Database
database_url: str
database_pool_size: int = 10
# API
api_host: str = "0.0.0.0"
api_port: int = 8000
debug: bool = False
# Security
secret_key: str
jwt_algorithm: str = "HS256"
access_token_expire_minutes: int = 15
# External services
redis_url: str = "redis://localhost:6379/0"
# Singleton via functools.cache
from functools import lru_cache
@lru_cache(maxsize=1)
def get_settings() -> Settings:
return Settings()
# Usage
settings = get_settings()
print(settings.database_url)
# FastAPI dependency
from fastapi import Depends
def get_db_url(settings: Settings = Depends(get_settings)) -> str:
return settings.database_url
Padrões de tratamento de erros
# Domain exceptions
class AppError(Exception):
def __init__(self, message: str, code: str):
super().__init__(message)
self.code = code
class NotFoundError(AppError):
def __init__(self, resource: str, id: int | str):
super().__init__(f"{resource} {id} not found", "NOT_FOUND")
class ValidationError(AppError):
def __init__(self, field: str, message: str):
super().__init__(f"{field}: {message}", "VALIDATION_ERROR")
# Never swallow exceptions silently
# BAD
try:
result = process(data)
except Exception:
pass # NEVER DO THIS
# GOOD: log and re-raise or handle specifically
import logging
logger = logging.getLogger(__name__)
try:
result = process(data)
except ValueError as e:
logger.warning(f"Invalid data: {e}")
raise ValidationError("data", str(e)) from e
except Exception as e:
logger.exception(f"Unexpected error processing data: {e}")
raise
Melhores práticas de desempenho
# 1. Use generators for large data
def process_large_file(path: str):
with open(path) as f:
for line in f: # not f.readlines()!
yield process_line(line)
# 2. Use slots for memory-efficient classes
class Point:
__slots__ = ('x', 'y') # saves 40-50% memory vs dict-based attrs
def __init__(self, x: float, y: float):
self.x = x
self.y = y
# 3. Profile before optimizing
import cProfile
cProfile.run('your_slow_function()', sort='cumulative')
# 4. Use collections for appropriate data structures
from collections import deque, defaultdict, Counter
# deque for queue (O(1) append/pop from either end)
queue = deque()
queue.appendleft(item) # O(1) vs list.insert(0, item) which is O(n)
# Counter for counting
word_count = Counter(text.split())
top_10 = word_count.most_common(10)
# 5. Prefer comprehensions over loops for transformations
squares = [x**2 for x in range(1000)] # faster than for loop + append
# 6. Use functools.cache for expensive pure functions
from functools import cache
@cache
def fibonacci(n: int) -> int:
if n < 2: return n
return fibonacci(n-1) + fibonacci(n-2)
Gerenciamento de Dependências
# 2026 standard: use uv (blazing fast, from Astral/ruff team)
pip install uv
# Create virtual environment and install deps (10x faster than pip)
uv venv && source .venv/bin/activate
uv pip install -r requirements.txt
# Or manage with pyproject.toml
uv add fastapi sqlalchemy pydantic # adds to pyproject.toml
uv add --dev pytest ruff mypy # dev dependencies
# Generate lockfile
uv lock
# Install from lockfile (reproducible)
uv sync
Lista de verificação de práticas recomendadas de Python
- Use dicas de tipo em todas as assinaturas de função
- Execute mypy ou Pyright em modo estrito
- Use ruff para linting e formatação
- Mais de 80% de cobertura de testes em lógica de negócios
- Configuração via variáveis de ambiente (Configurações Pydantic)
- Criação de log estruturado (structlog ou criação de log padrão)
- Hierarquia de exceções projetada (não apenas aumentar a exceção)
- Injeção de dependência (não estado global)
- Ambiente virtual por projeto (uv ou venv)
- Ganchos de pré-confirmação (ruff, mypy, testes)
As melhores práticas do Python em 2026 centram-se no conjunto de ferramentas moderno: ruff para linting/formatação, Pydantic v2 para validação, uv para gerenciamento de dependências e mypy/Pyright para verificação de tipo. Escreva código limpo com nomes significativos e dicas de tipo, projete hierarquias de exceções adequadas e teste completamente sua lógica de negócios. Essas práticas separam o código de produção sustentável dos scripts que somente o autor pode entender.
🔗 Share this article
✍️ Leave a Comment