Digamos que tenemos una función API compleja, importada de alguna biblioteca.
def complex_api_function(
number, <lots of positional arguments>,
<lots of keyword arguments>):
'''really long docstring'''
# lots of code
Quiero escribir un contenedor simple alrededor de esa función para hacer un pequeño cambio. Por ejemplo , debería ser posible pasar el primer argumento como una cadena. ¿Cómo documentar esto? Consideré las siguientes opciones:
Opción 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)
Desventaja: el usuario debe consultar los documentos de complex_api_function
para obtener información sobre *args
y **kwargs
. Necesita ajuste cuando la copia pegó secciones del complex_api_function
cambio.
Opcion 2:
Copie y pegue complex_api_function
la firma (en lugar de usar *args
y **kwargs
) y su cadena de documentos. Realice un pequeño cambio en la cadena de documentación que menciona que el primer argumento también puede ser una cadena. Agrega un ejemplo.
Desventaja: detallado, debe cambiarse cuando complex_api_function
cambia.
Opcion 3:
Decorar my_complex_api_function
con functools.wraps(complex_api_function)
.
Desventaja: no hay información que number
también pueda ser una cadena.
Estoy buscando una respuesta que no dependa de los detalles de los cambios my_complex_api_function
. El procedimiento debería funcionar para cualquier pequeño ajuste al original complex_api_function
.
fuente
complex_api_function
espera para su parámetro, ya que solo duplica la información (tal vez también tienen múltiples opciones). Presumiblemente, el usuario del contenedor ya está familiarizado con la función original y, si no, siempre puede señalarlos a los documentos originales. De todos modos, creo que este es el camino a seguir, solo documente lo que se agrega a la función original + proporcionando detalles sobre cómo ese nuevo tipo se convierte al original (esos detalles pueden ser importantes). Es decir, cómo se trata ese argumento para ser compatible con la función original.:ref:
en la cadena de documentación. Sin embargo, para pequeños cambios en la API, como pregunta el OP, permite a los usuarios comparar las funciones de manera más simple. En este caso, el esfuerzo mínimo podría dar un poco más de ganancia a los usuarios finales, y cuando leo documentos, en la mayoría de los casos, tomo un documento de 12 páginas sobre un documento de 6 páginas, porque es un poco más fácil de entender.Puede automatizar la "especialización" de la cadena de documentación original con un apéndice . Por ejemplo, pydoc está utilizando el atributo especial
__doc__
. Podría escribir un decorador que anule automáticamente la función original__doc__
con su anexo.Por ejemplo:
o...
Si ejecuta pydoc (
pydoc3 -w my_module.py
) produce: vista previa de html generado por pydocNota adicional: Si está utilizando Python 3, podría usar anotaciones para documentar el tipo (s) de los parámetros de su función. Ofrece muchos beneficios, no solo documentación. Por ejemplo:
fuente
a : float
en la parte superior y nunca llegará a la conclusión de que también podría usar unstr
aquí. Solo si por casualidad se desplazan hasta el final de los documentos, lo descubrirán.complex_package >= 1.1.0
. Ahora, cuando crea su paquete, debe usar una versión específica paracomplex_package
. Digamos que ya existecomplex_package==1.5.0
en pypi y agregaron un nuevo argumento de palabra clavecomplex_api_function
en la versión1.3.0
. De cualquier manera (usando1.1.0
o1.5.0
) tendrá información desactualizada / incorrecta para un subgrupo de sus usuarios en el documento. Lo mismo se aplica a los cambios futuros que aún no son públicos.No estoy seguro de si esto es lo que está buscando, pero ayuda a evitar la pregunta por completo.
fuente
wrapped_api_func
no tiene cadena de documentación, por lo que el problema de documentación no está resuelto.