Como Usar uma Lista de Regras Python
As páginas desta seção - uma lista mestre de 50 itens, mais bancos de 30 itens para código assíncrono, segurança e trabalho com dados/ML, mais um banco de 40 itens para design de API - podem parecer, à primeira vista, o mesmo conteúdo dividido em listas de tamanhos diferentes. Elas não são. Cada uma existe porque um domínio específico de trabalho em Python tem modos de falha que a lista geral não consegue cobrir sem se tornar longa demais para usar ou vaga demais para aplicar, e a própria divisão é uma decisão de design que vale a pena entender antes de usar qualquer lista individual.
Esta página explica esse design: por que as regras são agrupadas da maneira que são, o que separa uma regra que você pode colocar em um linter de uma que você só pode colocar em uma lista de verificação de revisão de código, e como uma lista de regras deve funcionar no dia a dia em vez de ficar sem ser lida em um wiki. Ela não reafirma as regras em si - 50 Regras Python que Todo Especialista Deveria Seguir e os bancos específicos de domínio já fazem isso.
Resumo
- Uma lista de regras é um conjunto codificado de padrões de equipe, dividido por domínio porque diferentes áreas de trabalho em Python (assíncrono, segurança, dados/ML, design de API) falham de maneiras diferentes e específicas.
- Por Que Importa: Usada corretamente, uma lista de regras remove debates repetitivos da revisão de código; usada como dogma, ela produz fadiga de alertas ou regras aplicadas onde não se encaixam no contexto.
- Conceitos-Chave: regra aplicável, regra de decisão de julgamento, banco específico de domínio, numeração de regra como navegação, exceção documentada.
- Quando Usar Este Modelo: Decidir qual lista se aplica a um trecho de código, configurar regras de linter/CI a partir de uma lista ou lidar com um desacordo sobre se uma regra se aplica em um caso específico.
- Limitações / Compromissos: Uma lista de regras captura o que uma equipe já sabe observar - ela não pode antecipar todos os novos modos de falha, e tratá-la como completa é em si um risco.
- Tópicos Relacionados: configuração de análise estática, padrões de revisão de código, documentação de onboarding, registros de decisões de arquitetura.
Fundamentos
Uma regra, no sentido que esta seção usa a palavra, é um padrão codificado: uma decisão que uma equipe já tomou uma vez, em geral, para que não precise ser re-argumentada em cada pull request.
Isso é diferente de uma lei - uma regra pode ser substituída quando o contexto específico a chama, desde que a substituição seja deliberada e visível, não ignorada silenciosamente.
A divisão mais clara em qualquer lista aqui é entre regras que são mecanicamente aplicáveis e regras que exigem julgamento.
Uma regra aplicável tem uma ferramenta que pode verificá-la automaticamente - ruff pegando um import não utilizado, mypy pegando uma dica de tipo ausente, um hook de pre-commit pegando um padrão de segredo codificado - para que um revisor humano nunca precise verificá-la manualmente.
Uma regra de decisão de julgamento não pode ser verificada por uma ferramenta - "exceções específicas sobre except: pass nu" requer entender o que o código realmente está tentando fazer, e "injeção de dependência sobre globais" requer entender o design, não apenas escanear a sintaxe.
Ambos os tipos de regras pertencem a uma lista útil, mas confundi-los é um erro comum: esperar que um linter aplique uma decisão de julgamento leva à decepção, e esperar que um revisor humano capture de forma confiável o que um linter deveria ter capturado leva à inconsistência.
Mecânicas e Interações
A estrutura desta seção - uma lista mestre geral mais bancos de domínio separados - existe porque os modos de falha específicos de domínio não se encaixam de forma limpa em uma única lista plana sem que ela fique muito grande para ser útil ou sem forçar regras não relacionadas a compartilhar a mesma seção.
50 Regras Python que Todo Especialista Deveria Seguir cobre o que se aplica amplamente: estilo, tipos, estrutura, testes e segurança básica, organizados em grupos numerados (estilo 1-10, 11-20 tipos e assim por diante).
Essa numeração é um auxílio de navegação, não uma ordem de prioridade - a regra 45 (SQL parametrizado) não é menos importante que a regra 5 (f-strings) apenas porque vem depois na lista; os grupos existem para que um leitor possa pular para a seção relevante, não para que as regras possam ser classificadas por número.
30 Regras Assíncronas, 30 Regras de Segurança para Python e 30 Regras de Código para Dados/ML existem como bancos separados porque cada domínio tem armadilhas invisíveis de uma perspectiva geral de Python: asyncio tem armadilhas específicas relacionadas a chamadas bloqueantes dentro de corrotinas e awaits esquecidos que não existem em código síncrono, segurança tem um modelo de ameaça inteiro em forma de OWASP que um guia de estilo geral nunca foi projetado para cobrir, e pipelines de dados/ML têm modos de falha de reprodutibilidade e vazamento de dados que não se parecem em nada com um bug típico de serviço web.
40 Regras de Design de API (FastAPI/Django/Flask) é específico de domínio da mesma forma, com escopo na camada de framework onde residem contratos de requisição/resposta, versionamento e consistência de formato de erro - preocupações que a lista geral aborda apenas superficialmente.
# Uma regra tornada mecanicamente aplicável e uma que não pode ser:
# a regra B008 do ruff pega isso automaticamente:
def handler(items=[]): # padrão mutável - sinalizado por análise estática
...
# mas nenhuma ferramenta pode verificar esta:
# "separar a lógica de domínio de I/O para que seja testável sem mocks"
# - isso é um julgamento de arquitetura que um revisor tem que fazer lendo o código.A conclusão dessa divisão é prática: ao adotar uma lista, mapeie cada regra aplicável a um código ruff select real, configuração mypy ou hook de pre-commit, e deixe as regras de decisão de julgamento para listas de verificação de revisão e conversas de onboarding - tentar forçar o segundo tipo em automação produz falsos positivos ou regras que ninguém consegue articular por que existem.
Considerações Avançadas e Aplicações
Uma lista de regras só permanece útil se uma equipe tratar desvios como algo a ser documentado, não algo a ser escondido.
Decisões de Arquitetura Python é o lar natural para essa documentação - uma exceção genuína a uma regra ("usamos um cache global mutável aqui porque X") pertence a um registro de decisão escrito, não a um comentário silencioso ou a um diff não explicado, porque o próximo engenheiro que ler esse código precisa saber que a exceção foi deliberada.
Isso importa mais à medida que uma lista cresce: uma lista de 50 itens adotada de uma vez, com todas as regras ruff habilitadas no primeiro dia, tende a produzir fadiga de alertas - os revisores começam a ignorar avisos em massa porque muitos dispararam ao mesmo tempo, o que frustra o propósito de automatizar qualquer um deles. Adotar incrementalmente, grupo por grupo, mantém cada nova verificação automatizada significativa em vez de ruído.
O outro eixo que vale a pena ser deliberado é o escopo: um script interno único relaxa razoavelmente as regras estruturais (organização de módulos, injeção de dependência) que uma biblioteca compartilhada não pode, enquanto as regras de segurança (consultas parametrizadas, manipulação de segredos) e as regras de estilo principal se aplicam em todos os lugares, não importa quão descartável o código pareça - "é apenas um script" não é uma defesa contra uma injeção de SQL.
| Tipo de lista | Aplicação | Público típico | Risco se mal utilizado |
|---|---|---|---|
| Lista mestre (geral) | Mista - algumas ruff/mypy, algumas revisão | Todos os engenheiros, onboarding | Aplicada muito rigidamente a código onde o escopo não se encaixa (scripts, protótipos) |
| Banco de domínio (assíncrono/segurança/dados-ML) | Principalmente revisão + ferramentas específicas de domínio (bandit, pip-audit) | Engenheiros que trabalham nesse domínio | Tratado como opcional porque é "especializado", perdido em código entre domínios |
| Referência de Estilo/PEP 8 | Quase inteiramente aplicável via ruff format | Todos os contribuidores, via portão de CI | Debates manuais de estilo em revisão, apesar de uma ferramenta já ter decidido |
| Referência de Problema/Solução | Não é uma lista de regras - pesquisa de idioma | Engenheiros inseguros sobre a abordagem idiomática | Confundido com uma lista de regras; documenta "como", não "deve" |
| Decisões de arquitetura | Não aplicável - registro de decisões de julgamento tomadas | Revisores avaliando exceções a outras regras | Tratado como documentação opcional em vez da fonte de verdade para "por que desviamos" |
Ler uma lista de regras bem significa reconhecer em qual linha uma determinada página se encaixa antes de aplicá-la - a Referência de Estilo e PEP 8 e a Referência de Problema / Solução não são bancos de regras prescritivos no mesmo sentido das listas numeradas; elas são material de referência que as listas numeradas assumem que você pode consultar quando uma regra referencia uma convenção ou um idioma pelo nome.
Conceitos Errôneos Comuns
- "Uma lista de regras é uma especificação completa de código correto." É um conjunto codificado de padrões que reflete modos de falha que a equipe já conhece; novos modos de falha - uma armadilha de uma nova biblioteca, um novo padrão de ataque - não aparecerão em uma lista escrita antes que alguém os atinja.
- "Toda regra na lista deve ser aplicada por CI." Apenas as mecanicamente verificáveis podem ser - forçar uma regra de decisão de julgamento ("separar lógica de domínio de I/O") em um portão automatizado produz falsos positivos ou requer um linter para entender a intenção, o que nenhum deles faz atualmente.
- "A numeração (1-50, 1-30) reflete a prioridade." Reflete o agrupamento para navegação - a regra 45 não é menos importante que a regra 5 porque um grupo posterior acontece de vir depois no documento.
- "Um banco específico de domínio é opcional se você já conhece as regras gerais." Modos de falha específicos de domínio (armadilhas de chamadas bloqueantes do asyncio, vazamento de dados de ML) são em grande parte invisíveis do conhecimento geral de Python sozinho - a lista geral não foi projetada para pegá-los e não tenta.
- "Desviar de uma regra significa que a regra estava errada." Uma exceção documentada e deliberada para um contexto específico é um uso normal e saudável de uma lista de regras; o modo de falha é uma exceção não documentada que um leitor futuro não tem como distinguir de um erro.
FAQs
Qual é a diferença entre uma regra e uma lei neste contexto?
Uma regra é um padrão codificado que a equipe concordou para não precisar re-argumentar a cada PR, mas pode ser deliberadamente substituída com uma razão documentada; uma lei implica que não há exceção legítima, o que não é como nenhuma lista nesta seção deve ser lida.
Como sei se uma regra pode ser automatizada?
Pergunte se uma ferramenta poderia verificá-la puramente a partir da sintaxe ou tipos sem entender a intenção do código - "sem except: nu" é verificável; "separar a lógica de domínio de I/O" requer que um humano julgue o design real, então permanece uma regra de tempo de revisão.
Por que esta seção tem uma lista de 50 itens E listas separadas de 30 itens para assíncrono, segurança e dados/ML?
Porque cada um desses domínios tem modos de falha invisíveis do conhecimento geral de Python - armadilhas específicas do asyncio, um modelo de ameaça de segurança, riscos de reprodutibilidade e vazamento específicos de ML - que ou inchariam uma lista geral além do útil ou seriam diluídos se fundidos a ela.
A numeração dentro de uma lista (como 1-10, 11-20) significa algo além de navegação?
Agrupa regras relacionadas por domínio (estilo, tipos, estrutura, testes, segurança) para que um leitor possa pular rapidamente para a seção relevante; não é um ranking de importância, e os grupos posteriores não são de menor prioridade que os anteriores.
Um script interno único deve seguir todas as regras da lista mestre?
Regras estruturais (layout de módulo, injeção de dependência, layout de src) são razoavelmente relaxadas para um script descartável, mas regras de segurança e correção principal - consultas parametrizadas, manipulação de segredos, validação de entrada - ainda se aplicam, não importa quão pequeno seja o script.
O que deve acontecer quando uma equipe decide quebrar uma regra de propósito?
A exceção deve ser documentada, tipicamente em um registro de decisão de arquitetura, explicando a razão específica - uma exceção não documentada é indistinguível de uma falha para o próximo engenheiro que ler esse código.
Por que não habilitar todas as regras ruff/mypy no primeiro dia para cobertura máxima?
Habilitar tudo de uma vez tende a produzir mais avisos do que uma equipe pode agir significativamente, e os revisores começam a ignorar o ruído em massa - adotar grupos de regras incrementalmente mantém cada nova verificação automatizada algo ao qual as pessoas realmente respondem.
A página Referência de Estilo e PEP 8 também é uma lista de regras?
É material de referência para o qual as regras numeradas apontam - ela documenta as convenções em detalhes em vez de afirmar novas regras "deve fazer" por si só, o que é uma função diferente dos bancos numerados.
Como a página Referência de Problema/Solução se relaciona com as listas de regras?
É uma pesquisa de idioma - "como faço X da maneira Pythonic" - não uma lista de regras prescritivas; ela responde a uma pergunta de "como" que as listas de regras não gastam espaço, já que uma regra como "use pathlib.Path" assume que você já sabe aproximadamente como usá-la.
Para quem a lista mestre é destinada versus um banco específico de domínio?
A lista mestre visa todos os engenheiros, independentemente do que estão construindo, tipicamente usada em onboarding e revisão geral de código; um banco de domínio visa engenheiros que trabalham ativamente nesse domínio - serviços assíncronos, código sensível à segurança ou pipelines de ML - onde a cobertura da lista geral acaba.
Qual é o risco real de tratar uma lista de regras como completa e final?
Cria uma falsa confiança de que seguir a lista garante a correção, quando a lista apenas reflete os modos de falha que a equipe já conhecia no momento em que foi escrita - novas ferramentas, novas bibliotecas e novos padrões de ataque não estarão nela até que alguém a atualize.
Com que frequência uma lista de regras deve ser realmente revisitada?
Sempre que a linguagem, o framework ou as ferramentas tiverem um lançamento importante, ou após um incidente real revelar um modo de falha que a lista não cobriu - uma lista estática fica obsoleta silenciosamente da mesma forma que qualquer outra documentação, se nada impulsionar uma revisão.
Relacionados
- 50 Regras Python que Todo Especialista Deveria Seguir - a lista mestre geral que esta página abrange
- 30 Regras Assíncronas - modos de falha específicos do asyncio
- 30 Regras de Segurança para Python - modelo de ameaça específico de segurança
- 40 Regras de Design de API (FastAPI/Django/Flask) - regras de contrato na camada de framework
- Decisões de Arquitetura Python - onde as exceções documentadas às regras pertencem
- Referência de Estilo e PEP 8 - o material de referência para o qual as regras de estilo apontam
Versões de Stack: Esta página é conceitual e não está vinculada a uma versão específica de stack.