Communitygithub.com

padrões-python

Padrões e práticas recomendadas de Python idiomático para criar aplicações robustas, eficientes e de fácil manutenção.

O que é padrões-python?

Esta habilidade oferece um guia abrangente sobre padrões de desenvolvimento Python e melhores práticas, ajudando agentes de IA e desenvolvedores a escrever código limpo, eficiente e de fácil manutenção. Ela cobre princípios fundamentais como priorizar legibilidade, explicitude sobre implícito e a filosofia EAFP (É Mais Fácil Pedir Perdão do que Permissão). A habilidade fornece exemplos práticos de uso de dicas de tipo modernas, tratamento de erros, gerenciadores de contexto, compreensões de listas e geradores, dataclasses, decoradores e padrões de concorrência (threading, multiprocessamento e async/await). Também inclui orientação sobre organização de pacotes, otimização de memória e desempenho, e integração com ferramentas Python essenciais como black, isort e ruff. Com suporte explícito para versões modernas do Python (3.9+), esta habilidade é útil para escrever ou revisar código Python, projetar módulos e refatorar aplicações existentes.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/python-patterns

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Padrões de Desenvolvimento Python

Padrões idiomáticos Python e melhores práticas para criar aplicações robustas, eficientes e de fácil manutenção.

Quando Ativar

  • Escrevendo novo código Python
  • Revisando código Python
  • Refatorando código Python existente
  • Projetando pacotes/módulos Python

Princípios Fundamentais

1. Legibilidade é Importante

Python prioriza a legibilidade. O código deve ser óbvio e fácil de entender.

# Bom: Claro e legível
def get_active_users(users: list[User]) -> list[User]:
    """Retorna apenas usuários ativos da lista fornecida."""
    return [user for user in users if user.is_active]


# Ruim: Inteligente, mas confuso
def get_active_users(u):
    return [x for x in u if x.a]

2. Explícito é Melhor que Implícito

Evite mágica; seja claro sobre o que seu código faz.

# Bom: Configuração explícita
import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

# Ruim: Efeitos colaterais ocultos
import some_module
some_module.setup()  # O que isso faz?

3. EAFP - É Mais Fácil Pedir Perdão do que Permissão

Python prefere tratamento de exceções a verificar condições.

# Bom: Estilo EAFP
def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
    try:
        return dictionary[key]
    except KeyError:
        return default_value

# Ruim: Estilo LBYL (Olhe Antes de Pular)
def get_value(dictionary: dict, key: str, default_value: Any = None) -> Any:
    if key in dictionary:
        return dictionary[key]
    else:
        return default_value

Dicas de Tipo

Anotações de Tipo Básicas

from typing import Optional, List, Dict, Any

def process_user(
    user_id: str,
    data: Dict[str, Any],
    active: bool = True
) -> Optional[User]:
    """Processa um usuário e retorna o User atualizado ou None."""
    if not active:
        return None
    return User(user_id, data)

Dicas de Tipo Modernas (Python 3.9+)

# Python 3.9+ - Use tipos embutidos
def process_items(items: list[str]) -> dict[str, int]:
    return {item: len(item) for item in items}

# Python 3.8 e anteriores - Use o módulo typing
from typing import List, Dict

def process_items(items: List[str]) -> Dict[str, int]:
    return {item: len(item) for item in items}

Aliases de Tipo e TypeVar

from typing import TypeVar, Union

# Alias de tipo para tipos complexos
JSON = Union[dict[str, Any], list[Any], str, int, float, bool, None]

def parse_json(data: str) -> JSON:
    return json.loads(data)

# Tipos genéricos
T = TypeVar('T')

def first(items: list[T]) -> T | None:
    """Retorna o primeiro item ou None se a lista estiver vazia."""
    return items[0] if items else None

Duck Typing Baseado em Protocolo

from typing import Protocol

class Renderable(Protocol):
    def render(self) -> str:
        """Renderiza o objeto para uma string."""

def render_all(items: list[Renderable]) -> str:
    """Renderiza todos os itens que implementam o protocolo Renderable."""
    return "\n".join(item.render() for item in items)

Padrões de Tratamento de Erros

Tratamento de Exceções Específicas

# Bom: Capture exceções específicas
def load_config(path: str) -> Config:
    try:
        with open(path) as f:
            return Config.from_json(f.read())
    except FileNotFoundError as e:
        raise ConfigError(f"Arquivo de configuração não encontrado: {path}") from e
    except json.JSONDecodeError as e:
        raise ConfigError(f"JSON inválido na configuração: {path}") from e

# Ruim: Except genérico
def load_config(path: str) -> Config:
    try:
        with open(path) as f:
            return Config.from_json(f.read())
    except:
        return None  # Falha silenciosa!

Encadeamento de Exceções

def process_data(data: str) -> Result:
    try:
        parsed = json.loads(data)
    except json.JSONDecodeError as e:
        # Encadeie exceções para preservar o traceback
        raise ValueError(f"Falha ao analisar dados: {data}") from e

Hierarquia de Exceções Personalizada

class AppError(Exception):
    """Exceção base para todos os erros da aplicação."""
    pass

class ValidationError(AppError):
    """Levantada quando a validação de entrada falha."""
    pass

class NotFoundError(AppError):
    """Levantada quando um recurso solicitado não é encontrado."""
    pass

# Uso
def get_user(user_id: str) -> User:
    user = db.find_user(user_id)
    if not user:
        raise NotFoundError(f"Usuário não encontrado: {user_id}")
    return user

Gerenciadores de Contexto

Gerenciamento de Recursos

# Bom: Usando gerenciadores de contexto
def process_file(path: str) -> str:
    with open(path, 'r') as f:
        return f.read()

# Ruim: Gerenciamento manual de recursos
def process_file(path: str) -> str:
    f = open(path, 'r')
    try:
        return f.read()
    finally:
        f.close()

Gerenciadores de Contexto Personalizados

from contextlib import contextmanager

@contextmanager
def timer(name: str):
    """Gerenciador de contexto para cronometrar um bloco de código."""
    start = time.perf_counter()
    yield
    elapsed = time.perf_counter() - start
    print(f"{name} levou {elapsed:.4f} segundos")

# Uso
with timer("processamento de dados"):
    process_large_dataset()

Classes de Gerenciadores de Contexto

class DatabaseTransaction:
    def __init__(self, connection):
        self.connection = connection

    def __enter__(self):
        self.connection.begin_transaction()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is None:
            self.connection.commit()
        else:
            self.connection.rollback()
        return False  # Não suprime exceções

# Uso
with DatabaseTransaction(conn):
    user = conn.create_user(user_data)
    conn.create_profile(user.id, profile_data)

Compreensões e Geradores

Compreensões de Lista

# Bom: Compreensão de lista para transformações simples
names = [user.name for user in users if user.is_active]

# Ruim: Loop manual
names = []
for user in users:
    if user.is_active:
        names.append(user.name)

# Compreensões complexas devem ser expandidas
# Ruim: Muito complexo
result = [x * 2 for x in items if x > 0 if x % 2 == 0]

# Bom: Use uma função geradora
def filter_and_transform(items: Iterable[int]) -> list[int]:
    result = []
    for x in items:
        if x > 0 and x % 2 == 0:
            result.append(x * 2)
    return result

Expressões Geradoras

# Bom: Gerador para avaliação lazy
total = sum(x * x for x in range(1_000_000))

# Ruim: Cria lista intermediária grande
total = sum([x * x for x in range(1_000_000)])

Funções Geradoras

def read_large_file(path: str) -> Iterator[str]:
    """Lê um arquivo grande linha por linha."""
    with open(path) as f:
        for line in f:
            yield line.strip()

# Uso
for line in read_large_file("huge.txt"):
    process(line)

Data Classes e Named Tuples

Data Classes

from dataclasses import dataclass, field
from datetime import datetime

@dataclass
class User:
    """Entidade User com __init__, __repr__ e __eq__ automáticos."""
    id: str
    name: str
    email: str
    created_at: datetime = field(default_factory=datetime.now)
    is_active: bool = True

# Uso
user = User(
    id="123",
    name="Alice",
    email="[email protected]"
)

Data Classes com Validação

@dataclass
class User:
    email: str
    age: int

    def __post_init__(self):
        # Valida formato do email
        if "@" not in self.email:
            raise ValueError(f"Email inválido: {self.email}")
        # Valida faixa etária
        if self.age < 0 or self.age > 150:
            raise ValueError(f"Idade inválida: {self.age}")

Named Tuples

from typing import NamedTuple

class Point(NamedTuple):
    """Ponto 2D imutável."""
    x: float
    y: float

    def distance(self, other: 'Point') -> float:
        return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5

# Uso
p1 = Point(0, 0)
p2 = Point(3, 4)
print(p1.distance(p2))  # 5.0

Decoradores

Decoradores de Função

import functools
import time

def timer(func: Callable) -> Callable:
    """Decorador para cronometrar a execução de uma função."""
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start
        print(f"{func.__name__} levou {elapsed:.4f}s")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)

# slow_function() imprime: slow_function levou 1.0012s

Decoradores Parametrizados

def repeat(times: int):
    """Decorador para repetir uma função várias vezes."""
    def decorator(func: Callable) -> Callable:
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            results = []
            for _ in range(times):
                results.append(func(*args, **kwargs))
            return results
        return wrapper
    return decorator

@repeat(times=3)
def greet(name: str) -> str:
    return f"Olá, {name}!"

# greet("Alice") retorna ["Olá, Alice!", "Olá, Alice!", "Olá, Alice!"]

Decoradores Baseados em Classe

class CountCalls:
    """Decorador que conta quantas vezes uma função é chamada."""
    def __init__(self, func: Callable):
        functools.update_wrapper(self, func)
        self.func = func
        self.count = 0

    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"{self.func.__name__} foi chamada {self.count} vezes")
        return self.func(*args, **kwargs)

@CountCalls
def process():
    pass

# Cada chamada a process() imprime a contagem de chamadas

Padrões de Concorrência

Threading para Tarefas Limitadas por I/O

import concurrent.futures
import threading

def fetch_url(url: str) -> str:
    """Busca uma URL (operação limitada por I/O)."""
    import urllib.request
    with urllib.request.urlopen(url) as response:
        return response.read().decode()

def fetch_all_urls(urls: list[str]) -> dict[str, str]:
    """Busca múltiplas URLs concorrentemente usando threads."""
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        future_to_url = {executor.submit(fetch_url, url): url for url in urls}
        results = {}
        for future in concurrent.futures.as_completed(future_to_url):
            url = future_to_url[future]
            try:
                results[url] = future.result()
            except Exception as e:
                results[url] = f"Erro: {e}"
    return results

Multiprocessamento para Tarefas Limitadas por CPU

def process_data(data: list[int]) -> int:
    """Computação intensiva de CPU."""
    return sum(x ** 2 for x in data)

def process_all(datasets: list[list[int]]) -> list[int]:
    """Processa múltiplos conjuntos de dados usando múltiplos processos."""
    with concurrent.futures.ProcessPoolExecutor() as executor:
        results = list(executor.map(process_data, datasets))
    return results

Async/Await para I/O Concorrente

import asyncio

async def fetch_async(url: str) -> str:
    """Busca uma URL assincronamente."""
    import aiohttp
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def fetch_all(urls: list[str]) -> dict[str, str]:
    """Busca múltiplas URLs concorrentemente."""
    tasks = [fetch_async(url) for url in urls]
    results = await asyncio.gather(*tasks, return_exceptions=True)
    return dict(zip(urls, results))

Organização de Pacotes

Estrutura Padrão de Projeto

myproject/
├── src/
│   └── mypackage/
│       ├── __init__.py
│       ├── main.py
│       ├── api/
│       │   ├── __init__.py
│       │   └── routes.py
│       ├── models/
│       │   ├── __init__.py
│       │   └── user.py
│       └── utils/
│           ├── __init__.py
│           └── helpers.py
├── tests/
│   ├── __init__.py
│   ├── conftest.py
│   ├── test_api.py
│   └── test_models.py
├── pyproject.toml
├── README.md
└── .gitignore

Convenções de Import

# Bom: Ordem de import - stdlib, terceiros, local
import os
import sys
from pathlib import Path

import requests
from fastapi import FastAPI

from mypackage.models import User
from mypackage.utils import format_name

# Bom: Use isort para ordenação automática de imports
# pip install isort

init.py para Exportações de Pacote

# mypackage/__init__.py
"""mypackage - Um pacote Python de exemplo."""

__version__ = "1.0.0"

# Exporta classes/funções principais no nível do pacote
from mypackage.models import User, Post
from mypackage.utils import format_name

__all__ = ["User", "Post", "format_name"]

Memória e Desempenho

Usando slots para Eficiência de Memória

# Ruim: Classe regular usa __dict__ (mais memória)
class Point:
    def __init__(self, x: float, y: float):
        self.x = x
        self.y = y

# Bom: __slots__ reduz o uso de memória
class Point:
    __slots__ = ['x', 'y']

    def __init__(self, x: float, y: float):
        self.x = x
        self.y = y

Gerador para Grandes Dados

# Ruim: Retorna lista completa em memória
def read_lines(path: str) -> list[str]:
    with open(path) as f:
        return [line.strip() for line in f]

# Bom: Produz linhas uma de cada vez
def read_lines(path: str) -> Iterator[str]:
    with open(path) as f:
        for line in f:
            yield line.strip()

Evite Concatenação de Strings em Loops

# Ruim: O(n²) devido à imutabilidade de strings
result = ""
for item in items:
    result += str(item)

# Bom: O(n) usando join
result = "".join(str(item) for item in items)

# Bom: Usando StringIO para construção
from io import StringIO

buffer = StringIO()
for item in items:
    buffer.write(str(item))
result = buffer.getvalue()

Integração com Ferramentas Python

Comandos Essenciais

# Formatação de código
black .
isort .

# Linting
ruff check .

# Type checking
mypy .

# Testes
pytest .

# Building
python -m build

Configuração pyproject.toml

[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.backends._legacy:_Backend"

[tool.black]
line-length = 88
target-version = ['py39', 'py310', 'py311']

[tool.isort]
profile = "black"
line_length = 88

[tool.ruff]
line-length = 88
target-version = "py39"
select = [
    "E",  # pycodestyle errors
    "W",  # pycodestyle warnings
    "F",  # pyflakes
    "I",  # isort
    "N",  # pep8-naming
    "D",  # pydocstyle
]

[tool.mypy]
python_version = "3.9"
warn_unused_configs = true
warn_redundant_casts = true
warn_unused_ignores = true

Referências

Licença

Este guia de padrões é disponibilizado sob a Licença MIT.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

Habilidades Relacionadas