Python Docstrings

Você escreveu uma função útil. Daqui a três meses, você (ou uma colega) vai querer usá-la de novo: o que ela faz? O que é cada parâmetro? Em que unidade vai o preço? A resposta fica numa docstring (de documentation string, "texto de documentação"): um texto entre três aspas, logo abaixo do def, que explica a função. Diferente de um comentário, a docstring fica guardada dentro da função, e o Python sabe mostrá-la quando alguém pede ajuda com help().

Você vai aprender
  • O que é uma docstring e onde ela fica (a primeira linha do corpo da função).
  • A diferença entre docstring e comentário (#).
  • A escrever docstrings de uma linha e de várias linhas, do jeito que a comunidade Python costuma escrever.
  • A ler a documentação com help() e com o atributo __doc__.
  • A documentar um arquivo inteiro (a docstring do módulo).
  • Os erros reais: docstring fora do lugar, sem recuo e com as aspas abertas.

A ideia: a etiqueta do pote

Na cozinha da Ana, os potes de tempero são todos iguais. Sem etiqueta, ela precisa abrir, cheirar e provar para saber o que é cada um. Com uma etiqueta colada no pote ("Páprica defumada. Usar pouco: é forte."), qualquer pessoa da casa sabe o que tem dentro sem abrir.

A docstring é a etiqueta da função. Quem vai usar a função não precisa ler o código de dentro: lê a etiqueta. E, como a etiqueta está colada no pote, ela vai junto para onde a função for: para outro arquivo que a importa, para o help(), para o editor de código que mostra a dica quando você digita o nome da função.


1. A primeira docstring

def troco(pago, total):
    """Devolve quanto de troco a Ana tem de dar."""
    return pago - total


print(troco(20, 13.5))
def troco(pago, total):
Uma função comum (aula Funções).
"""
Três aspas duplas abrem a docstring. É um texto (uma string) como outro qualquer, só que com aspas triplas, que permitem várias linhas.
Devolve quanto de troco a Ana tem de dar.
O que a função faz, numa frase. Costuma começar com um verbo ("Devolve", "Calcula", "Mostra") e terminar com ponto.
"""
Três aspas fecham a docstring. Numa docstring de uma linha, abre e fecha na mesma linha.
O lugar
Tem de ser a primeira coisa dentro da função, logo abaixo do def, com o mesmo recuo (4 espaços) do resto do corpo. Em qualquer outro lugar, não é docstring (veja Quando dá errado).
$ python3 troco.py
6.5

A docstring não muda nada no que a função faz: ela não aparece na saída nem atrapalha o return. Para que serve, então? Para ser lida, como você vai ver agora.


2. Lendo a documentação: help() e __doc__

A Ana guardou as funções da padaria num arquivo próprio, padaria.py, que outros programas podem importar (aula Criando seu Módulo):

"""Funções da padaria do bairro: preços e troco."""


def preco_com_desconto(preco, porcentagem):
    """Devolve o preço depois de aplicar o desconto.

    preco: o preço original, em reais.
    porcentagem: o desconto, de 0 a 100 (10 quer dizer 10%).
    """
    return preco - preco * porcentagem / 100


def troco(pago, total):
    """Devolve quanto de troco a Ana tem de dar."""
    return pago - total

help(): a ajuda do Python

A função embutida help() ("ajuda") mostra a documentação de qualquer coisa: uma função, um módulo inteiro. Ela monta a página com o nome, os parâmetros e a docstring:

$ python3 -c "import padaria; help(padaria.troco)"
Help on function troco in module padaria:

troco(pago, total)
    Devolve quanto de troco a Ana tem de dar.

Help on function troco in module padaria:
"Ajuda sobre a função troco, do módulo padaria."
troco(pago, total)
O nome e os parâmetros, tirados do def. Isso o help() descobre sozinho.
Devolve quanto de troco a Ana tem de dar.
A docstring. Isso é o que só você pode escrever.

(O python3 -c "…" roda um programa de uma linha, escrito ali mesmo; é só um atalho para não criar mais um arquivo.) E com o módulo inteiro:

$ python3 -c "import padaria; help(padaria)"
Help on module padaria:

NAME
    padaria - Funções da padaria do bairro: preços e troco.

FUNCTIONS
    preco_com_desconto(preco, porcentagem)
        Devolve o preço depois de aplicar o desconto.

        preco: o preço original, em reais.
        porcentagem: o desconto, de 0 a 100 (10 quer dizer 10%).

    troco(pago, total)
        Devolve quanto de troco a Ana tem de dar.

FILE
    /home/ana/padaria.py

Uma página de manual completa, montada só com as docstrings: o NAME ("nome") usa a docstring do módulo (a primeira linha do arquivo), FUNCTIONS lista as funções com as suas docstrings, e FILE diz onde está o arquivo.

O help() no modo interativo

No modo interativo (>>>), help() mostra o mesmo texto, mas numa tela à parte, para você poder rolar páginas longas com as setas. No terminal da Ana, depois de import padaria e help(padaria.preco_com_desconto), a última linha dessa tela é:

Help on preco_com_desconto line 1/7 (END) (press h for help or q to quit)

"(FIM) (aperte h para ajuda ou q para sair)". Aperte q para voltar ao >>>. Experimente com as funções embutidas: help(len), help(print).

__doc__: a docstring como texto

A docstring fica guardada num atributo da função chamado __doc__ (com dois sublinhados de cada lado; em inglês se lê "dunder doc"). Dá para mostrá-la com print:

import padaria

print(padaria.troco.__doc__)
print("---")
print(padaria.preco_com_desconto.__doc__)
print("---")
print(padaria.__doc__)
$ python3 usa_doc.py
Devolve quanto de troco a Ana tem de dar.
---
Devolve o preço depois de aplicar o desconto.

preco: o preço original, em reais.
porcentagem: o desconto, de 0 a 100 (10 quer dizer 10%).

---
Funções da padaria do bairro: preços e troco.

Repare que os 4 espaços de recuo das linhas de dentro da docstring não aparecem: o Python tira o recuo em comum ao guardar o texto. A linha vazia antes do segundo --- é a última linha da docstring, a das três aspas sozinhas.

As funções embutidas também têm docstring (em inglês):

$ python3 -c "print(len.__doc__)"
Return the number of items in a container.

"Devolve o número de itens de um contêiner." É daí que o help(len) tira o texto.

Missão: o print mostra None, porque a função não tem docstring. Escreva uma docstring de uma linha, com três aspas, dizendo Devolve a área do retângulo.

def area(largura, altura):
    return largura * altura


print(area.__doc__)
def area(largura, altura):
    """Devolve a área do retângulo."""
    return largura * altura


print(area.__doc__)

3. Docstring de várias linhas

Quando uma frase não basta, a docstring cresce. O costume da comunidade Python (descrito num documento chamado PEP 257) é:

  1. Primeira linha: um resumo curto, numa frase, logo depois das aspas de abertura.
  2. Uma linha em branco. Ela separa o resumo do resto; ferramentas como o help() e os editores de código usam a primeira linha como resumo.
  3. Os detalhes: o que é cada parâmetro, o que a função devolve, cuidados.
  4. As aspas de fechamento sozinhas na última linha.
def media(notas):
    """Devolve a média das notas, com uma casa decimal.

    notas: uma lista de números de 0 a 10. Não pode estar vazia.
    Devolve um float, por exemplo 7.3.
    """
    return round(sum(notas) / len(notas), 1)
O que vale a pena escrever
  • O que a função faz e o que devolve, não como ela faz por dentro (isso o código já mostra).
  • O que cada parâmetro espera: o tipo, a unidade (reais? centavos? de 0 a 100 ou de 0 a 1?), os limites.
  • O que pode dar errado: "não pode estar vazia".

Uma docstring que só repete o nome da função ("""Função troco.""") não ajuda ninguém.

Exemplos dentro da docstring

Muita gente coloca, na docstring, um exemplo de uso no formato do modo interativo (>>> troco(20, 13.5) e a resposta embaixo). O Python tem até uma ferramenta, o doctest, que roda esses exemplos e confere se a resposta continua certa. Ela é assunto da aula Testes.


4. Docstring do módulo

Um arquivo .py também pode ter docstring: é um texto entre três aspas na primeira linha do arquivo, antes de tudo (antes até dos import). Foi o que a Ana fez no padaria.py:

"""Funções da padaria do bairro: preços e troco."""

Ela aparece no help(padaria), na linha NAME, e em padaria.__doc__. As classes (aula Classes e Objetos) também têm docstring, logo abaixo da linha class, do mesmo jeito.


Formas diferentes de fazer a mesma coisa

FormaExemploQuando usar
Docstring de uma linha"""Devolve o troco."""Funções simples, em que uma frase explica tudo
Docstring de várias linhasResumo, linha em branco, detalhesQuando há parâmetros que precisam de explicação, unidades, limites
Comentário ## o desconto vem em porcentagemPara explicar como uma linha do código funciona, para quem lê o código (aula Comentários). Não aparece no help()
''' (aspas simples triplas)'''Devolve o troco.'''Funciona igual, mas o costume (PEP 257) é """. Prefira """
Uma aspa só"Devolve o troco."Também vira docstring se estiver no lugar certo, mas não aceita várias linhas. Prefira """ sempre
Docstring × comentário, em uma frase

A docstring é para quem vai usar a função (o que ela faz); o comentário é para quem vai mexer no código (como ele faz). Veja a diferença no help() logo abaixo, em Quando dá errado.


Quando dá errado

Um comentário no lugar da docstring
def troco(pago, total):
    # Devolve quanto de troco a Ana tem de dar.
    return pago - total


print(troco.__doc__)
help(troco)
$ python3 comentario.py
None
Help on function troco in module __main__:

troco(pago, total)

Não há erro, mas a explicação sumiu: __doc__ vale None ("nada", aula O Valor None), e o help() mostra só o nome e os parâmetros. O Python joga fora os comentários ao ler o programa; eles não ficam guardados em lugar nenhum. (__main__ é o nome que o Python dá ao arquivo que você mandou rodar.) Como consertar: troque o # por uma docstring: """Devolve quanto de troco a Ana tem de dar.""".

A docstring fora do lugar
def troco(pago, total):
    resultado = pago - total
    """Devolve quanto de troco a Ana tem de dar."""
    return resultado


print(troco.__doc__)
$ python3 fora_do_lugar.py
None

De novo None, e sem erro. O texto entre aspas está lá, mas não é a primeira coisa do corpo da função: veio depois do resultado = …. Aí ele vira só um texto solto, que o Python calcula e descarta. Como consertar: a docstring vai logo abaixo do def, antes de qualquer outra linha.

Missão: o programa mostra None em vez da documentação. Mova a docstring para o lugar certo.

def troco(pago, total):
    resultado = pago - total
    """Devolve quanto de troco a Ana tem de dar."""
    return resultado


print(troco.__doc__)
def troco(pago, total):
    """Devolve quanto de troco a Ana tem de dar."""
    resultado = pago - total
    return resultado


print(troco.__doc__)
A docstring sem recuo
def troco(pago, total):
"""Devolve quanto de troco a Ana tem de dar."""
    return pago - total
$ python3 sem_recuo.py
  File "/home/ana/sem_recuo.py", line 2
    """Devolve quanto de troco a Ana tem de dar."""
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
IndentationError: expected an indented block after function definition on line 1

"Erro de indentação: esperava um bloco recuado depois da definição de função da linha 1." A docstring faz parte do corpo da função, então precisa do mesmo recuo de 4 espaços (aula Sintaxe e Indentação). Repare que não há Traceback: o Python nem começou a rodar o programa, porque não conseguiu nem ler o arquivo. Como consertar: 4 espaços antes das aspas.

As aspas que não fecham

Uma aspa só não aceita quebra de linha:

def troco(pago, total):
    "Devolve quanto de troco
    a Ana tem de dar."
    return pago - total
$ python3 aspas_simples.py
  File "/home/ana/aspas_simples.py", line 2
    "Devolve quanto de troco
    ^
SyntaxError: unterminated string literal (detected at line 2)

"Texto não terminado (detectado na linha 2)": a aspa abriu e a linha acabou sem fechá-la. E quando as três aspas abrem, mas a pessoa esquece de fechar:

def troco(pago, total):
    """Devolve quanto de troco a Ana tem de dar.
    return pago - total


print(troco(20, 13.5))
$ python3 aspas_fim.py
  File "/home/ana/aspas_fim.py", line 2
    """Devolve quanto de troco a Ana tem de dar.
    ^
SyntaxError: unterminated triple-quoted string literal (detected at line 6)

"Texto de aspas triplas não terminado (detectado na linha 6)". O Python foi engolindo tudo como parte do texto, o return e o print inclusive, até o fim do arquivo (linha 6), procurando as três aspas de fechamento. O ^ aponta para onde o texto começou, que é onde você deve procurar. Como consertar: feche com """ no fim da docstring.


Referência rápida

EscritaO que faz
"""Resumo em uma linha.""" logo abaixo do defDocstring de uma linha
"""Resumo. / linha em branco / detalhes / """Docstring de várias linhas (PEP 257)
"""…""" na primeira linha do arquivoDocstring do módulo
help(funcao)Mostra a página de ajuda (nome, parâmetros, docstring)
help(modulo)Mostra a ajuda do módulo inteiro
funcao.__doc__A docstring como texto (None se não houver)
qSai da tela do help() no modo interativo
SintomaCausa provável
__doc__ vale None, help() sem descriçãoNão há docstring: foi usado #, ou o texto não é a primeira linha do corpo
IndentationError: expected an indented block after function definitionA docstring (ou o corpo) sem os 4 espaços de recuo
SyntaxError: unterminated string literalDocstring de várias linhas com uma aspa só: use """
SyntaxError: unterminated triple-quoted string literalFaltou fechar o """

Exercícios

1. As aspas

Complete a docstring de uma linha (as aspas de abrir e de fechar são iguais):

def dobro(n): Devolve o dobro de n. return n * 2

2. O atributo

Complete para mostrar a docstring da função dobro:

print(dobro.)

3. Onde fica a docstring de uma função?

4. A função tem só um comentário # Calcula o troco. logo abaixo do def. O que print(troco.__doc__) mostra?

5. Pelo costume da PEP 257, o que vem logo depois da primeira linha (o resumo) numa docstring de várias linhas?

Missão final: documentando a média

Missão: escreva uma docstring de várias linhas para a função media: na primeira linha, o resumo Devolve a média das notas.; depois, uma linha em branco; depois, pelo menos uma linha explicando o parâmetro notas.

def media(notas):
    return sum(notas) / len(notas)


print(media.__doc__)
def media(notas):
    """Devolve a média das notas.

    notas: uma lista de números de 0 a 10. Não pode estar vazia.
    """
    return sum(notas) / len(notas)


print(media.__doc__)

Resumo

  • A docstring é um texto entre """ que fica logo abaixo do def, como primeira coisa do corpo, com o mesmo recuo.
  • Ela explica o que a função faz, o que espera e o que devolve, para quem vai usá-la. O comentário # explica como, para quem vai mexer no código.
  • Uma linha: """Devolve o troco.""". Várias linhas: resumo, linha em branco, detalhes, """ sozinho no fim (PEP 257).
  • help(funcao) mostra a página de ajuda; no modo interativo, saia com q. funcao.__doc__ devolve o texto, ou None.
  • Um texto entre aspas na primeira linha do arquivo é a docstring do módulo.
  • Fora do lugar ou com #, não é docstring: None, sem erro. Sem recuo, IndentationError; sem fechar, SyntaxError: unterminated ….