Monday, March 30, 2015

dunderdoc, a simple Python introspection utility

By Vasudev Ram



While browsing Python documentation, I came up with the idea of this small Python introspection utility.

It prints the __doc__ attribute (the docstring) of each item in a list of names given as argument to it. So I called the function 'dunderdoc()' - because it is an informal convention in the Python community to call attributes such as __name__, that begin and end with a double underscore, dunder-name, and so on.

Here is the code for dunderdoc.py:

"""
dunderdoc.py
A Python function to print the .__doc__ attribute (i.e. the docstring) 
of each item in a list of names given as the argument.
The function is called dunderdoc because it is an informal convention 
in the Python community to call attributes such as __name__, that begin 
and end with a double underscore, dunder-name, and so on.
Author: Vasudev Ram - http://www.dancingbison.com
Copyright 2015 Vasudev Ram
"""

def dunderdoc(names):
    for name in names:
        print '-' * 72
        print name + '.__doc__:'
        print eval(name).__doc__
    print '-' * 72

# Call dunderdoc() on some basic objects:

a = 1 # an integer
b = 'abc' # a string
c = False # a boolean
d = () # a tuple
e = [] # a list
f = {} # a dict
g = set() # a set

dunderdoc(('a', 'b', 'c', 'd', 'e', 'f', 'g'))

# Call dunderdoc() on some user-defined objects:

class Foo(object):
    """
    A class that implements Foo instances.
    """

def bar(args):
    """
    A function that implements bar functionality.
    """

dunderdoc(['Foo', 'bar'])

And here is the output of running dunderdoc.py with the example calls to the dunderdoc() function:
------------------------------------------------------------------------
a.__doc__:
int(x=0) -> int or long
int(x, base=10) -> int or long

Convert a number or string to an integer, or return 0 if no arguments
are given.  If x is floating point, the conversion truncates towards zero.
If x is outside the integer range, the function returns a long instead.

If x is not a number or if base is given, then x must be a string or
Unicode object representing an integer literal in the given base.  The
literal can be preceded by '+' or '-' and be surrounded by whitespace.
The base defaults to 10.  Valid bases are 0 and 2-36.  Base 0 means to
interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4
------------------------------------------------------------------------
b.__doc__:
str(object='') -> string

Return a nice string representation of the object.
If the argument is a string, the return value is the same object.
------------------------------------------------------------------------
c.__doc__:
bool(x) -> bool

Returns True when the argument x is true, False otherwise.
The builtins True and False are the only two instances of the class bool.
The class bool is a subclass of the class int, and cannot be subclassed.
------------------------------------------------------------------------
d.__doc__:
tuple() -> empty tuple
tuple(iterable) -> tuple initialized from iterable's items

If the argument is a tuple, the return value is the same object.
------------------------------------------------------------------------
e.__doc__:
list() -> new empty list
list(iterable) -> new list initialized from iterable's items
------------------------------------------------------------------------
f.__doc__:
dict() -> new empty dictionary
dict(mapping) -> new dictionary initialized from a mapping object's
    (key, value) pairs
dict(iterable) -> new dictionary initialized as if via:
    d = {}
    for k, v in iterable:
        d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
    in the keyword argument list.  For example:  dict(one=1, two=2)
------------------------------------------------------------------------
g.__doc__:
set() -> new empty set object
set(iterable) -> new set object

Build an unordered collection of unique elements.
------------------------------------------------------------------------
------------------------------------------------------------------------
Foo.__doc__:

    A class that implements Foo instances.
    
------------------------------------------------------------------------
bar.__doc__:

    A function that implements bar functionality.
    
------------------------------------------------------------------------

The image at the top of the post is of Auguste Rodin's Le Penseur (The Thinker).

- Enjoy.

- Vasudev Ram - Online Python training and programming

Dancing Bison Enterprises

Signup to hear about new products that I create.

Posts about Python  Posts about xtopdf

Contact Page

2 comments:

Vasudev Ram said...

Here is a usage of the term dunderdoc from 2009:

http://www.mike-griffith.com/blog/2009/03/notes-from-pycon-2009/

Vasudev Ram said...

In the above code for dunderdoc(), it should be clear why I could not use just:

print name.__doc__

(without wrapping the name in eval()).

If anyone is wondering why I could not use:

print eval(name.__doc__)

, just try it and see why :)