Digamos que temos uma função API complexa, importada de alguma biblioteca.
def complex_api_function(
number, <lots of positional arguments>,
<lots of keyword arguments>):
'''really long docstring'''
# lots of code
Quero escrever um invólucro simples em torno dessa função para fazer uma pequena alteração. Por exemplo , deve ser possível passar o primeiro argumento como uma string. Como documentar isso? Eu considerei as seguintes opções:
Opção 1:
def my_complex_api_function(number_or_str, *args, **kwargs):
'''
Do something complex.
Like `complex_api_function`, but first argument can be a string.
Parameters
----------
number_or_str : int or float or str
Can be a number or a string that can be interpreted as a float.
<copy paste description from complex_api_function docstring>
*args
Positional arguments passed to `complex_api_function`.
**kwargs
Keyword arguments passed to `complex_api_function`.
Returns
-------
<copy paste from complex_api_function docstring>
Examples
--------
<example where first argument is a string, e.g. '-5.0'>
'''
return complex_api_function(float(number_or_str), *args, **kwargs)
Desvantagem: o usuário precisa consultar os documentos complex_api_function
para obter informações sobre *args
e **kwargs
. Precisa de ajuste quando a cópia colou as seções da complex_api_function
alteração.
Opção 2:
Copie e cole complex_api_function
a assinatura (em vez de usar *args
e **kwargs
) e sua documentação. Faça uma pequena alteração na string de documento que menciona que o primeiro argumento também pode ser uma string. Adicione um exemplo.
Desvantagem: detalhada, deve ser alterada quando houver complex_api_function
alterações.
Opção 3:
Decore my_complex_api_function
com functools.wraps(complex_api_function)
.
Desvantagem: não há informações que number
também possam ser uma sequência.
Estou procurando uma resposta que não se baseie nos detalhes do que muda my_complex_api_function
. O procedimento deve funcionar para qualquer pequeno ajuste no original complex_api_function
.
fonte
complex_api_function
espera para seu parâmetro, pois isso apenas duplica as informações (talvez elas também tenham várias opções). Presumivelmente, o usuário do wrapper já está familiarizado com a função original e, caso contrário, você pode sempre apontá-los para os documentos originais. De qualquer forma, acho que esse é o caminho a seguir, apenas documente o que é adicionado à função original + fornecendo detalhes sobre como esse novo tipo é convertido no original (esses detalhes podem ser importantes). Ou seja, como esse argumento é tratado para ser compatível com a função original.:ref:
na docstring. No entanto, para pequenas alterações na API - como o OP está perguntando -, permite que os usuários comparem as funções de maneira mais simples. Nesse caso, o esforço mínimo pode dar um pouco mais de ganho aos usuários finais - e quando eu leio documentos, eu levo um documento de 12 páginas sobre um documento de 6 páginas na maioria dos casos, porque é um pouco mais fácil de entender.Você pode automatizar a "especialização" da docstring original com um adendo . Por exemplo, pydoc está usando o atributo especial
__doc__
. Você pode escrever um decorador que substitua automaticamente a função original__doc__
pelo seu adendo.Por exemplo:
ou...
Se você executar o pydoc (
pydoc3 -w my_module.py
), ele produzirá: visualização do html gerado pelo pydocNota adicional: Se você estiver usando o Python 3, poderá usar anotações para documentar o (s) tipo (s) dos seus parâmetros de função. Oferece muitos benefícios, não apenas documentação. Por exemplo:
fonte
a : float
a sequência de documentos estendida, verá no topo e nunca chegará à conclusão de que também pode usar umstr
aqui. Somente se, por acaso, rolarem até o final dos documentos, eles a descobrirão.complex_package >= 1.1.0
. Agora, quando você cria seu pacote, você precisa usar uma versão específicacomplex_package
. Digamos que já existacomplex_package==1.5.0
no pypi e eles adicionaram um novo argumento de palavra-chavecomplex_api_function
na versão1.3.0
. De qualquer forma (usando1.1.0
ou1.5.0
), você terá informações desatualizadas / incorretas para um subgrupo de usuários no documento. O mesmo se aplica a mudanças futuras que ainda não são públicas.Não tenho certeza se é isso que você está procurando, mas ajuda a evitar a pergunta completamente.
fonte
wrapped_api_func
não possui docstring, portanto, o problema da documentação não foi resolvido.