O poder de uma boa documentação em Python


Acho difícil alguém discordar o quão delicioso é para um desenvolvedor quando uma ferramenta necessária é devidamente documentada. E é ainda mais difícil alguém discordar da importância da documentação no desenvolvimento de API's, bibliotecas ou frameworks. A documentação é uma parte crucial do processo de desenvolvimento de software; uma ferramenta mal documentada pode não atrair desenvolvedores entusiastas e isso pode impactar diretamente no sucesso do seu projeto. Agora que chegamos a um acordo, aposto que você está pensando: "Eu comento todo o meu código, então eu não preciso ler esse artigo sobre documentação". E é por isso que eu preciso explicar:
A diferença entre documentação e comentários
Uma documentação é a receita de bolo do seu projeto. Ela diz para o usuário como usar a sua ferramenta sem que seja necessário acessar e entender o seu código. Comentários, por outro lado, são notas para você e outros desenvolvedores que estarão olhando o código-fonte. Eles explicam o porquê de uma determinada lógica, um workaround específico, ou marcam TODOs.
A documentação é voltada para o usuário da sua biblioteca, API ou framework. Os comentários são para os mantenedores e contribuidores do código.
Documentando no Python
Agora que você já entendeu que documentar é uma parte importante do processo. E você que é menos experiente deve estar se perguntando, como fazer isso e o custo de uma boa documentação. Eu trago boas notícias, uma documentação pode ser gerada automaticamente, e neste artigo vou te mostrar como e até o final da leitura você será um expert.
Antes de qualquer coisa eu gostaria de explicar o porquê da minha escolha por Python, já que a maioria das linguagens possui ferramentas para gerar documentações. A resposta é bem simples, primeiro, é a linguagem que eu mais tenho domínio, e fica mais fácil para mim abordar esse tema considerado tão importante, segundo, é uma das melhores linguagens quando se trata de documentação.
Docstrings
O coração da documentação em Python são as docstrings. Podem ser encontradas na PEP-257 Docstring Conventions ou na documentação do Python em 4.8.7. Documentation Strings. Resumindo a documentação, uma docstring é uma string literal que precede a primeira declaração em um módulo, função, classe ou método, tornando-se o atributo especial __doc__
(ou como chamamos dunder __doc__
) desse objeto.
Existem dois formatos de docstrings:
One-line vs Multi-line docstrings
O primeiro caso é usado para descrições mais óbvias e resumos e tudo deve estar na mesma linha, a abertura e fechamento de aspas triplas e o texto. Veja esse exemplo tirado da própria documentação:
def kos_root():
"""Return the pathname of the KOS root directory."""
global kos_root
# ...
O segundo caso deve-se quebrar uma linha após a abertura de aspas triplas e o texto pode ser mais elaborado tendo o fechamento das aspas triplas na próxima linha.
def complex(real=0.0, imag=0.0):
"""Form a complex number.
Keyword arguments:
real -- the real part (default 0.0)
imag -- the imaginary part (default 0.0)
"""
if real == 0.0 and imag == 0.0:
return complex_zero
# ...
Agora que você já entendeu como funciona, vamos ver como a mágica acontece.
Gerando documentação com Python
Eu vou criar um exemplo de uma biblioteca de código de um mensageiro fictício e vamos gerar a documentação desse exemplo com Sphinx. Mas antes vamos entender as:
Convenções de documentação e formatadores de docstrings
Não existem muitos critérios e nem regras para a escolha da convenção ou o formatador, fica por sua escolha mas é importante que você escolha um formato que seja compatível com a ferramenta que irá gerar o site da sua documentação. Segue uma lista com os principais formatadores e todos são compatíveis com Sphinx:
Eu deixei o link para você estudar essas convenções no futuro, mas por enquanto não precisa focar nisso, todas são muito parecidas, com algumas pequenas diferenças. Nesse exemplo usaremos o reStructured Text pois é o padrão do Sphinx e é muito parecido com Markdown.
Gerando uma documentação com Sphinx
Como mencionei anteriormente, vou criar um exemplo de uma biblioteca de código de um mensageiro fictício e vamos gerar a documentação desse exemplo com Sphinx. Mas antes de botar a mão na massa, vamos entender o que é o Sphinx e por que ele é tão popular na comunidade Python.
O que é o Sphinx?
Sphinx é uma ferramenta poderosa que transforma arquivos de texto simples em diversos formatos de saída, como HTML, PDF, ePub e mais. Ele foi originalmente criado para a documentação da linguagem Python e, desde então, tornou-se a escolha padrão para muitos projetos Python e até mesmo para projetos em outras linguagens. Sua principal força reside na capacidade de processar reStructuredText (e Markdown, com extensões), uma linguagem de marcação fácil de ler, e integrá-lo perfeitamente com o código Python para extrair docstrings automaticamente.
Por que escolher o Sphinx?
Automação: Ele pode extrair automaticamente a documentação das docstrings do seu código Python usando a extensão
autodoc
. Isso significa que sua documentação e seu código permanecem sincronizados com mais facilidade.Formatos de saída múltiplos: Precisa de um site HTML? Um PDF para impressão? O Sphinx cuida disso.
Referências cruzadas extensivas: Crie links facilmente entre diferentes partes da sua documentação, módulos, classes e funções.
Temas e extensibilidade: Customize a aparência da sua documentação com temas (como o popular
sphinx_rtd_theme
usado pelo Read the Docs) e adicione funcionalidades com uma vasta gama de extensões.Suporte a reStructuredText e Markdown: Embora o reStructuredText seja o padrão e ofereça mais funcionalidades, o Sphinx também pode lidar com Markdown através de extensões, oferecendo flexibilidade.
Ampla adoção: Muitos projetos grandes utilizam o Sphinx, o que significa uma comunidade grande, muitos recursos e tutoriais disponíveis.
Mãos à obra: configurando o Sphinx
Instalação:
Primeiro, você precisará instalar o Sphinx. Recomendo também instalar o
sphinx_rtd_theme
para um visual moderno:pip install sphinx sphinx-rtd-theme
Iniciando o projeto de documentação:
Navegue até o diretório raiz do seu projeto Python e execute o assistente de configuração do Sphinx:
sphinx-quickstart
Este comando fará uma série de perguntas para configurar seu projeto de documentação. Algumas das opções importantes:
Nome do projeto: O nome da sua biblioteca ou aplicação.
Nome do autor: Seu nome ou o nome da sua organização.
Versão do projeto: A versão atual do seu projeto.
Extensões: Aqui é crucial habilitar algumas extensões. Pressione 'y' para:
sphinx.ext.autodoc
: Para incluir documentação de docstrings.sphinx.ext.napoleon
: Se você planeja usar docstrings no estilo Google ou NumPy.sphinx.ext.viewcode
: Para adicionar links para o código fonte.sphinx.ext.githubpages
: Se você planeja hospedar no GitHub Pages.
Após responder a todas as perguntas, o sphinx-quickstart
criará um diretório docs
(ou o nome que você escolheu) com vários arquivos, incluindo:
conf.py
: O arquivo de configuração principal do Sphinx. É aqui que você define o tema, ativa extensões, e mais importante, informa ao Sphinx onde encontrar seu código Python.index.rst
: A página inicial da sua documentação.Makefile
(oumake.bat
no Windows): Arquivos de utilidade para construir sua documentação.
Configurando o conf.py:
Abra o arquivo docs/conf.py e faça algumas edições essenciais:
Descomente e ajuste o
sys.path
: Para que oautodoc
encontre seus módulos Python, você precisa adicionar o diretório do seu código aosys.path
. Se sua estrutura de projeto for algo como:meu_projeto/ ├── docs/ │ └── conf.py └── src/ └── meu_mensageiro/ └── __init__.py └── core.py
Você adicionaria:
import os import sys sys.path.insert(0, os.path.abspath('../src')) # Ajuste conforme sua estrutura
Defina o tema HTML: Para usar o tema Read the Docs:
html_theme = 'sphinx_rtd_theme'
Verifique as extensões: Garanta que
sphinx.ext.autodoc
está na listaextensions
.
Exemplo prático: Documentando nossa biblioteca de mensageiro fictício
Vamos supor que temos um módulo core.py
dentro de src/meu_mensageiro/
com o seguinte conteúdo:
# src/meu_mensageiro/core.py
"""
Módulo principal do Mensageiro Fictício.
Este módulo contém as funcionalidades centrais para enviar e receber mensagens.
"""
MAX_MESSAGE_LENGTH = 1024
"""Constante que define o tamanho máximo de uma mensagem."""
class Message:
"""
Representa uma mensagem no sistema.
:param sender: O remetente da mensagem.
:type sender: str
:param content: O conteúdo da mensagem.
:type content: str
:raises ValueError: Se o conteúdo da mensagem exceder `MAX_MESSAGE_LENGTH`.
"""
def __init__(self, sender: str, content: str):
if len(content) > MAX_MESSAGE_LENGTH:
raise ValueError("Conteúdo da mensagem muito longo.")
self.sender = sender
self.content = content
self.is_sent = False
def send(self) -> bool:
"""
Envia a mensagem.
Simula o envio de uma mensagem. Em um cenário real, isso se conectaria
a um serviço de mensageria.
:return: True se a mensagem foi enviada com sucesso, False caso contrário.
:rtype: bool
"""
print(f"Mensagem de {self.sender} enviada: {self.content}")
self.is_sent = True
return True
def receive_message(user: str) -> Message | None:
"""
Simula o recebimento de uma nova mensagem para um usuário.
:param user: O nome do usuário para verificar mensagens.
:type user: str
:return: Um objeto :class:`Message` se houver uma nova mensagem, ou None caso contrário.
:rtype: Message or None
"""
# Em um sistema real, haveria uma lógica para buscar mensagens
if user == "ricardo":
return Message("servidor_central", "Bem-vindo ao Mensageiro Fictício!")
return None
Neste exemplo, usamos o formato reStructuredText para as docstrings, como discutido. Observe como descrevemos parâmetros (:param:
), tipos (:type:
), o que é retornado (:return:
, :rtype:
) e exceções (:raises:
). Informações detalhadas sobre como escrever docstrings podem ser encontradas em tutoriais como o do DataCamp sobre docstrings em Python.
Criando arquivos .rst para o autodoc:
Agora, vamos dizer ao Sphinx para gerar documentação para o nosso módulo core. Crie um arquivo chamado meu_mensageiro.rst dentro do diretório docs/ com o seguinte conteúdo:
.. automodule:: meu_mensageiro.core :members: :undoc-members: :show-inheritance:
.. automodule:: meu_mensageiro.core
: Diz ao Sphinx para documentar o módulomeu_mensageiro.core
.:members:
: Inclui todos os membros públicos (funções, classes, variáveis) do módulo.:undoc-members:
: Inclui membros que não têm docstrings (use com cautela, o ideal é documentar tudo).:show-inheritance:
: Mostra as classes base para as classes documentadas.
Agora, adicione este novo arquivo ao seu toctree
principal no arquivo docs/index.rst
:
.. toctree::
:maxdepth: 2
:caption: Conteúdo:
meu_mensageiro
Gerando a documentação:
Volte para o diretório docs/ no seu terminal e execute:
make html
Se tudo estiver configurado corretamente, o Sphinx processará seus arquivos
.rst
e as docstrings do seu código, gerando a documentação em HTML no diretóriodocs/_build/html/
. Abra o arquivoindex.html
nesse diretório para ver sua documentação em ação!Você verá uma página bem formatada com a descrição do seu módulo, a constante
MAX_MESSAGE_LENGTH
, a classeMessage
com seus métodos, e a funçãoreceive_message
, tudo extraído das docstrings que você escreveu.
Dicas para uma documentação de qualidade com Sphinx:
Seja consistente: Escolha um estilo de docstring (reStructuredText, Google, NumPy) e mantenha-o em todo o projeto. A consistência é fundamental para a legibilidade.
Documente a API pública: Foque em documentar a interface que outros desenvolvedores (ou você mesmo no futuro) usarão. Uma boa documentação de API é crucial.
Inclua exemplos de uso: Docstrings são um ótimo lugar para pequenos exemplos. Para exemplos mais complexos, considere criar seções separadas na sua documentação ou até mesmo um diretório
examples/
.Mantenha atualizado: Documentação desatualizada é pior do que nenhuma documentação. Faça da atualização da documentação parte do seu processo de desenvolvimento.
Use referências cruzadas: Sphinx facilita a criação de links para outras partes da sua documentação usando roles como
:mod:
,:func:
,:class:
. Isso torna a navegação muito mais fluida.Explore extensões: O ecossistema de extensões do Sphinx é vasto. Precisa de diagramas? Suporte a Jupyter Notebooks? Provavelmente existe uma extensão para isso.
A documentação é uma parte vital de qualquer projeto de software, grande ou pequeno. Mesmo que você esteja trabalhando em projetos mais simples, como explorar a criação de um site com Python puro, sem framework (usando CGI), entender como articular a funcionalidade do seu código é uma habilidade valiosa que se reflete na qualidade da sua documentação.
Conclusão
Dominar ferramentas como o Sphinx e adotar boas práticas de escrita de docstrings pode parecer um esforço extra inicialmente, mas os benefícios a longo prazo são imensos. Uma documentação clara, concisa e abrangente economiza tempo, reduz a frustração, facilita a colaboração e, em última análise, contribui significativamente para o sucesso e a adoção do seu projeto Python.
Lembre-se: um código bem documentado não é apenas um presente para os outros, é um presente para o seu eu futuro. Invista tempo em documentar seu trabalho, e você colherá os frutos.
Espero que este guia tenha convencido você do poder de uma boa documentação em Python e o tenha preparado para começar a documentar seus próprios projetos como um verdadeiro expert!
Subscribe to my newsletter
Read articles from Ricardo Santos directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Ricardo Santos
Ricardo Santos
Sou um desenvolvedor de software movido pela curiosidade e pela paixão por tecnologia. Aqui no blog, compartilho minhas aventuras desbravando novas ferramentas, frameworks e ideias, sempre testando o que há de mais interessante no mundo digital.