A versão original(em inglês) pode ser encontrada aqui
Um guia com as "melhores das melhores práticas" (BOBP) para o desenvolvimento em Python.
- "Construa ferramentas para os outros como você gostaria que elas fossem construídas para você." - Kenneth Reitz
- "Simplicidade é sempre melhor que funcionalidade." - Pieter Hintjens
- "Fit the 90% use-case. Ignore the nay sayers." - Kenneth Reitz
- "Bonito é melhor que feio." - PEP 20
- Contrua para código aberto(mesmo para projeto de código fechado).
- "Explícito é melhor que implícito" - PEP 20
- "Legibilidade conta." - PEP 20
- "Qualquer um pode consertar qualquer coisa." - Khan Academy Development Docs
- Conserte cada janela quebrada (design ruim, decisão errada ou código ruim) assim que for descoberto.
- "Agora é melhor que nunca." - PEP 20
- Teste impiedosamente. Escreva documentação para novas funcionalidades.
- Ainda mais importante que o desenvolvimento guiado por testes(TDD) é o desenvolvimento guiado para humanos
- Estas diretrizes podem --e provavelmente vão-- sofrer alterações.
Siga o PEP 8, quando sensato.
- Variáveis, funções, métodos, pacotes, módulo
lower_case_with_underscores
- Classes e exceções
CapWords
- Métodos protegidos e funções internas
_single_leading_underscore(self, ...)
- Métodos privados
__double_leading_underscore(self, ...)
- Constantes
ALL_CAPS_WITH_UNDERSCORES
Evite variáveis de uma letra (especialmente l
, O
, I
).
Exceção: Em blocos muito curtos, quando o significado é claramente visível para o contexto
Tudo bem
for e in elements:
e.mutate()
Evite rótulos redundantes.
Sim
import audio
core = audio.Core()
controller = audio.Controller()
Não
import audio
core = audio.AudioCore()
controller = audio.AudioController()
Prefira "notação reversa".
Sim
elements = ...
elements_active = ...
elements_defunct = ...
Não
elements = ...
active_elements = ...
defunct_elements ...
Evite métodos getter e setter.
Sim
person.age = 42
Não
person.set_age(42)
Use 4 espação--nunca tabulação. Isso é o bastante
Importe todo o módulo ao invés de símbolos individuais. Por exemplo, para um módulo canteen
que tem um arquivo canteen/sessions.py
,
Sim
import canteen
import canteen.sessions
from canteen import sessions
Não
from canteen import get_user # Symbol from canteen/__init__.py
from canteen.sessions import get_session # Symbol from canteen/sessions.py
Exceção: Para código de terceiros onde a documentação explicitamente diz para importar símbolos individuais.
Fundamentaço: Evita circular imports. See here.
Coloque todas as importações no topo do arquivo, dividido em 3 sessões, cada uma separada por uma linha em branco, nessa ordem:
- Importação do sistema
- Importação de terceiros
- Importação local
Fundamentação: Torna claro de onde cada módulo está vindo.
Siga as diretrizes de docstring PEP 257, reStructured Text e Sphinx podem te ajudar a seguir essas normas.
Use docstring de uma linha para funções óbvias.
"""Return the pathname of ``foo``."""
Docstring de múltiplas linhas deve incluir
- Linha de sumário
- Caso de uso, se for aplicável
- Argumentos
- Tipo de retorno e semântica, ao menos que retorne None
"""Train a model to classify Foos and Bars.
Usage::
>>> import klassify
>>> data = [("green", "foo"), ("orange", "bar")]
>>> classifier = klassify.train(data)
:param train_data: A list of tuples of the form ``(color, label)``.
:rtype: A :class:`Classifier <Classifier>`
"""
Notas
- Use action words ("Return") rather than descriptions ("Returns").
- Documentar o método
__init__
no docstring da classe.
class Person(object):
"""A simple representation of a human being.
:param name: A string, the person's name.
:param age: An int, the person's age.
"""
def __init__(self, name, age):
self.name = name
self.age = age
Use com moderação. Prefira um código legível a um monte de comentários. Muitas vezes, métodos pequenos são mais efetivos que comentários.
Não
# If the sign is a stop sign
if sign.color == 'red' and sign.sides == 8:
stop()
Sim
def is_stop_sign(sign):
return sign.color == 'red' and sign.sides == 8
if is_stop_sign(sign):
stop()
When you do write comments, remember: "Strunk and White apply." - PEP 8
Não se estresse. Entre 80 e 100 caracteres está bom.
Use parentesis para continuação de linha.
wiki = (
"The Colt Python is a .357 Magnum caliber revolver formerly manufactured "
"by Colt's Manufacturing Company of Hartford, Connecticut. It is sometimes "
'referred to as a "Combat Magnum". It was first introduced in 1955, the '
"same year as Smith & Wesson's M29 .44 Magnum."
)
Esforce-se para atingir uma cobertura de 100%, mas não fique obcecado com esse índice.
- Use nomes longos e descritivos. Use long, descriptive names. Isso muitas vezes remove a necessidade de docstring em métodos de teste.
- Testes devem ser isolados. Não interaja com um banco de dados de produço ou rede. Use um banco de dados para testes e o destrua quando terminar ou use objetos mock.
- Prefira factories a fixtures.
- Nunca deixe um teste incompleto passar, senão você corre o risco de esquecê-lo. Em vez disso adicione um marcador como
assert False, "TODO: finish me"
.
- Concentre-se em um pequeno pedaço de funcionalidade.
- Deve ser rápido, mas um teste lento é melhor que nenhum teste.
- Muitas vezes faz sentido ter uma classe TestCase para uma única classe ou modelo.
import unittest
import factories
class PersonTest(unittest.TestCase):
def setUp(self):
self.person = factories.PersonFactory()
def test_has_age_in_dog_years(self):
self.assertEqual(self.person.dog_years, self.person.age / 7)
Testes funcionais são testes de alto nível que estão mais próximos de como o usuário final irá interagir com sua aplicação. Eles so normalmente utilizados para aplicações web e GUI.
- Escreva testes como cenários. Nomes de TestCase e métodos devem ser lidos como uma descrição de cenário.
- Use comentários para escrever histórias antes de escrever código de teste
import unittest
class TestAUser(unittest.TestCase):
def test_can_write_a_blog_post(self):
# Goes to the her dashboard
...
# Clicks "New Post"
...
# Fills out the post form
...
# Clicks "Submit"
...
# Can see the new post
...
Observe como o TesteCase e o método podem ser lidos como: "Test A User can write a blog post".