Documentation

I decided to explore what is considered to be the proper or best documentation methods. Up til now I just adopted a few things I saw in other scripts or carried over ideas I learned from java programming.

Header

#!/usr/bin/env python
# -*- coding: utf-8 -*-

These should be the top two lines. The first line is necessary for programs to be cross-platform. The second line is optional, where the default encoding is ASCII. The ‘utf-8’ can be replaced with other encoding types.

Next should be a multi-line docstring. It must come next and before all code in order for python to recognize it as the main docstring and attach it to the ‘__doc__’ identifier. Thus,

print objname.__doc__

will print out the contents of this string. The first line should be a short description followed by a blank line. This brief description will show up after the filename (or ‘__name__’ if it is explicitly defined below the docstring but doing this could cause other problems).

In [4]: import SIFT_pack_v3 as SIFT

In [5]: help SIFT
------> help(SIFT)
Help on module SIFT_pack_v3:

NAME
    SIFT_pack_v3 - Created on Sat Dec 24 22:52:12 2011

FILE
    c:\dropbox\my programming\sift_pack_v3.py
...

This shows how the help output is formatted. The first line of my docstring is a creation date statement instead of a description and this is printed out after the file name and dash. The help format follows this up with the file location. After skipping a line from the short description or statement you can write a more verbose description and instructions.

Epydoc seems to be a prominent auto documenting program. If you write you docstrings conforming to their standards, then it can produce nice looking html documentation pages for the code. Details on how to do epydoc formatting are at epydoc.

After the main docstring, it is recommended that you have import statements, beginning with built-in modules and followed by any others.

I’m not completely clear about the difference between using @version in the docstring versus declaring the __version__ variable outside the docstring. They are two different conventions, where @version conforms to the epydoc style, but epydoc will still recognize __version__. You can make up as many of these as you like but only a few are recognized by epydoc. The recognized ones are:

__author__
__authors__
__contact__
__copyright__
__license__
__deprecated__
__date__
__version__

This is described as using module variables as module metadata. There is a way to get epydoc to recognize other metadata (variables) so you can have the best of both worlds. See adding new fields for epydoc.

The next section should have global variables, but it is recommended that globals be avoided. I don’t remember why and I still use them for setting the working directory or testing for the existence of necessary files.

All the functions follow. The first item within the class or function block should also be a docstring. Again, the first line should be a short summary. Then describe the inputs and outputs in the epydoc style,

def example():
    """
    @arg x: This is a description of
        the parameter x to a function.
        Note that the description is
        indented four spaces. Also
        can use @param instead.
    @type x: This is a description of
        x's type.
    @return: This is a description of
        the function's return value.
    @rtype: This is a description of
        the return value's type.
    """

Apart from epydoc formatting, a docstring can be arranged anyway you want. Here is an example found on PEP 257:

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword arguments:
    real -- the real part (default 0.0)
    imag -- the imaginary part (default 0.0)

    """
    if imag == 0.0 and real == 0.0: return complex_zero
    ...

Finally, the very last item should be:

if __name__ == '__main__':
    main()

This will automatically run ‘main()’ when the program is ran and not when the module is simply imported. This needs to be the last item to ensure that all functions are loaded prior to running the main method regardless of order they are arranged.

On a side note, dir(object) in IPython console will print out a list of all namespaces, functions, and variables(outside of functions) within the object.

Leave a comment