Estoy escribiendo una clase ligera cuyos atributos están destinados a ser de acceso público y solo a veces se anulan en instancias específicas. No hay ninguna disposición en el lenguaje Python para crear cadenas de documentos para atributos de clase, o cualquier tipo de atributos, para el caso. ¿Cuál es la forma esperada y admitida, debería haber una, de documentar estos atributos? Actualmente estoy haciendo este tipo de cosas:
class Albatross(object):
"""A bird with a flight speed exceeding that of an unladen swallow.
Attributes:
"""
flight_speed = 691
__doc__ += """
flight_speed (691)
The maximum speed that such a bird can attain.
"""
nesting_grounds = "Raymond Luxury-Yacht"
__doc__ += """
nesting_grounds ("Raymond Luxury-Yacht")
The locale where these birds congregate to reproduce.
"""
def __init__(self, **keyargs):
"""Initialize the Albatross from the keyword arguments."""
self.__dict__.update(keyargs)
Esto dará como resultado que el docstring de la clase contenga la sección de docstring estándar inicial, así como las líneas agregadas para cada atributo mediante una asignación aumentada a __doc__
.
Aunque este estilo no parece estar expresamente prohibido en las pautas de estilo de la cadena de documentos , tampoco se menciona como una opción. La ventaja aquí es que proporciona una forma de documentar atributos junto con sus definiciones, al mismo tiempo que crea una cadena de documentos de clase presentable y evita tener que escribir comentarios que reiteran la información de la cadena de documentos. Todavía estoy un poco molesto por tener que escribir los atributos dos veces; Estoy considerando usar las representaciones de cadena de los valores en la cadena de documentos para al menos evitar la duplicación de los valores predeterminados.
¿Es esta una violación atroz de las convenciones comunitarias ad hoc? ¿Está bien? ¿Existe una forma mejor? Por ejemplo, es posible crear un diccionario que contenga valores y cadenas de documentos para los atributos y luego agregar el contenido a la clase __dict__
y la cadena de documentos hacia el final de la declaración de la clase; esto aliviaría la necesidad de escribir dos veces los nombres y valores de los atributos. editar : esta última idea, creo, no es realmente posible, al menos no sin construir dinámicamente toda la clase a partir de datos, lo que parece una muy mala idea a menos que haya alguna otra razón para hacerlo.
Soy bastante nuevo en Python y todavía estoy trabajando en los detalles del estilo de codificación, por lo que las críticas no relacionadas también son bienvenidas.
attribute doc string
mencionado en PEP 257 que no es muy conocido y parece difícil de encontrar que pueda responder a la pregunta de los OP, y es compatible con algunas herramientas de origen. Esta no es una opinión. Es un hecho, y parte del lenguaje, y casi exactamente lo que quiere el OP.Respuestas:
Para evitar confusiones: el término propiedad tiene un significado específico en Python. De lo que estás hablando es de lo que llamamos atributos de clase . Dado que siempre se actúa sobre ellos a través de su clase, encuentro que tiene sentido documentarlos dentro de la cadena de documentos de la clase. Algo como esto:
Creo que es mucho más fácil para los ojos que el enfoque de tu ejemplo. Si realmente quisiera que apareciera una copia de los valores de los atributos en la cadena de documentos, los pondría al lado o debajo de la descripción de cada atributo.
Tenga en cuenta que en Python, las cadenas de documentos son miembros reales de los objetos que documentan, no simplemente anotaciones de código fuente. Dado que las variables de atributo de clase no son objetos en sí mismas, sino referencias a objetos, no tienen forma de contener cadenas de documentos propias. Supongo que podría defender las cadenas de documentos en las referencias, tal vez para describir "lo que debería ir aquí" en lugar de "lo que realmente está aquí", pero me resulta bastante fácil hacerlo en la cadena de documentos de la clase que las contiene.
fuente
flight_speed = 691; flight_speed.__doc__ = "blah blah"
. Creo que esto es lo que mencionas en tu edición . Desafortunadamente, esto no funciona para instancias de (¿la mayoría?) Tipos integrados (comoint
en ese ejemplo). Funciona para instancias de tipos definidos por el usuario. =========== En realidad, hubo un PEP (lo siento, olvide el número) que propuso agregar cadenas de documentos para los atributos de clase / módulo, pero se rechazó porque no pudieron encontrar una manera de aclararlo si las cadenas de documentos eran para los atributos anteriores o siguientes.Citas PEP257: Convenciones de cadenas de documentos, en la sección ¿Qué es una cadena de documentos? Se indica:
Y esto se explica con más detalle en PEP 258: Cadenas de documentación de atributos. Como se explica arriba ʇsәɹoɈ. un atributo no es un objeto que pueda poseer un __doc__ por lo que no aparecerán en
help()
o pydoc. Estas cadenas de documentación solo se pueden utilizar para la documentación generada.Se utilizan en Sphinx con la directiva autoattribute
Sphinx puede usar comentarios en una línea antes de una tarea o un comentario especial después de una tarea o una cadena de documentos después de la definición que se autodocumentará.
fuente
Podría abusar de las propiedades en este sentido. Las propiedades contienen un captador, un definidor, un eliminador y una cadena de documentos . Ingenuamente, esto se volvería muy detallado:
Entonces tendrás una cadena de documentos que pertenece a Cx:
Hacer esto para muchos atributos es engorroso, pero podría imaginarse una función auxiliar myprop:
Entonces, llamar a Pythons interactivo
help
dará:que creo que debería ser más o menos lo que buscas.
Editar : Ahora me doy cuenta de que quizás podamos evitar tener que pasar el primer argumento a
myprop
, porque el nombre interno no importa. Si las llamadas posteriores demyprop
pueden comunicarse de alguna manera entre sí, podría decidir automáticamente sobre un nombre de atributo interno largo e improbable. Estoy seguro de que hay formas de implementar esto, pero no estoy seguro de si valen la pena.fuente