Skip to content

Instantly share code, notes, and snippets.

@eltonplima
Forked from sloria/bobp-python.md
Last active July 18, 2017 19:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eltonplima/64613d93242fe53bbfe097712a53f005 to your computer and use it in GitHub Desktop.
Save eltonplima/64613d93242fe53bbfe097712a53f005 to your computer and use it in GitHub Desktop.
A "Best of the Best Practices" (BOBP) guide to developing in Python.

Guia das melhores das melhores práticas para Python

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.

Geral

Valores

  • "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).

Diretrizes gerais de desenvolvimento

  • "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.

Em particular

Estilo

Siga o PEP 8, quando sensato.

Nomenclatura

  • 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
Diretrizes gerais para nomenclatura

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)

Indentação

Use 4 espação--nunca tabulação. Isso é o bastante

Imports

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:

  1. Importação do sistema
  2. Importação de terceiros
  3. Importação local

Fundamentação: Torna claro de onde cada módulo está vindo.

Documentação

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
Comentários

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

Comprimento das linhas

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."
)

Testando

Esforce-se para atingir uma cobertura de 100%, mas não fique obcecado com esse índice.

Diretrizes gerais de testes

  • 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".

Testes unitários

  • 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

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".

Inspired by...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment