How to document class attributes in Python?

I am writing a lightweight class whose attributes are intended for public access and are only occasionally redefined in specific instances. In Python, there are no conditions for creating docstrings for class attributes or any attributes. What is an acceptable way, should it be, to document these attributes? I am currently doing things like this:

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) 

This will result in the docstring class containing the initial standard docstring string, as well as the rows added for each attribute, using the extended __doc__ assignment.

Although this style is not explicitly prohibited in the docstring style rules , it is also not mentioned as an option. The advantage here is that it provides a way to document attributes along with their definitions, while creating a presentable class docstring and avoiding the need to write comments that repeat information from docstring. It still annoys me that I have to actually write the attributes twice; I am considering using string representations of values ​​in a docstring to avoid duplicating default values.

Is this a heinous violation of special community conventions? This is normal? Is there a better way? For example, you can create a dictionary containing values ​​and docstrings for attributes, and then add content to the __dict__ and docstring classes at the end of the class declaration; this will make it easier to enter attribute names and values ​​twice. edit : this last idea, in my opinion, is actually not possible, at least not without dynamically building the entire class from the data, which seems like a really bad idea if there are no other reasons for this.

I am new to python and still developing coding style details, so non-critical criticisms are also welcome.

+93
python class documentation docstring
Jun 16 '10 at 6:58
source share
3 answers

To avoid confusion: the term property has special meaning in Python. What you are talking about is what we call class attributes . Since they are always accessed through their class, I believe it makes sense to document them in the line of the class document. Something like that:

 class Albatross(object): """A bird with a flight speed exceeding that of an unladen swallow. Attributes: flight_speed The maximum speed that such a bird can attain. nesting_grounds The locale where these birds congregate to reproduce. """ flight_speed = 691 nesting_grounds = "Throatwarbler Man Grove" 

I think this is a lot easier for the eyes than the approach in your example. If I really wanted a copy of the attribute values ​​to appear on the document line, I would place them next to or below the description of each attribute.

Remember that in Python, document strings are actual members of the objects they document, not just source code annotations. Since class attribute variables are not objects themselves, but are references to objects, they cannot contain their own lines of documents. I suppose you could argue in favor of the documentation lines on the links, perhaps describe “what should be here” instead of “what is really here”, but I find it pretty easy to do this in the containing class line of the document.

+69
Jun 16 '10 at 7:25
source share

You are citing PEP257: Conventions, under What is a Specified String?

String literals found elsewhere in Python code can also act as documentation. They are not recognized by the Python byte code compiler and are not available as attributes of the runtime object (i.e., they are not assigned to __doc__), but software tools can extract two types of additional documentation lines:

String literals that occur immediately after a simple assignment at the top level of a __init__ module, class, or method are called "attribute documentation strings."

And this is explained in more detail in PEP 258: Attribute Documentation Lines. As explained above ʇsәɹoɈ. the attribute is not an object to which __doc__ can belong, so it will not appear in help() or pydoc. These documentation lines can only be used for generated documentation.

They are used in Sphinx with the autoattribute directive.

Sphinx can use comments in a line before an assignment, or a special comment after an assignment, or a documentation line after a definition that will be automatically documented.

+24
Mar 04 2018-12-12T00:
source share

You can abuse properties for this purpose. Properties contain the receiver, installer, uninstaller, and documentation string. It would be naive to get very verbose:

 class C: def __init__(self): self._x = None @property def x(self): """Docstring goes here.""" return self._x @x.setter def x(self, value): self._x = value @x.deleter def x(self): del self._x 

Then you will have a documentation line owned by Cx:

 In [24]: print(Cx__doc__) Docstring goes here. 

It is quite difficult to do this for many attributes, but you can imagine the helper function myprop:

 def myprop(x, doc): def getx(self): return getattr(self, '_' + x) def setx(self, val): setattr(self, '_' + x, val) def delx(self): delattr(self, '_' + x) return property(getx, setx, delx, doc) class C: a = myprop("a", "Hi, I'm A!") b = myprop("b", "Hi, I'm B!") In [44]: c = C() In [46]: cb = 42 In [47]: cb Out[47]: 42 In [49]: print(Cb__doc__) Hi, I'm B! 

Then, calling the Pythons interactive help will give:

 Help on class C in module __main__: class C | Data descriptors defined here: | | a | Hi, I'm A! | | b | Hi, I'm B! 

what I think should be pretty much what you are after.

Edit : Now I understand that we can possibly avoid having to pass the first argument to myprop at all, because the internal name does not matter. If subsequent calls to myprop can somehow communicate with each other, it can automatically select a long and unlikely internal attribute name. I'm sure there are ways to implement this, but I'm not sure if they are worth it.

+10
Mar 20 '13 at 23:55
source share



All Articles