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