The recipe provides a method "describe" which takes a module as argument and describes classes, methods and functions in the module. The method/function description provides information on the function/method arguments using the inspect module.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | #!/usr/bin/env python
# Describe classes, methods and functions in a module.
# Works with user-defined modules, all Python library
# modules, including built-in modules.
import inspect
import os, sys
INDENT=0
def wi(*args):
""" Function to print lines indented according to level """
if INDENT: print ' '*INDENT,
for arg in args: print arg,
print
def indent():
""" Increase indentation """
global INDENT
INDENT += 4
def dedent():
""" Decrease indentation """
global INDENT
INDENT -= 4
def describe_builtin(obj):
""" Describe a builtin function """
wi('+Built-in Function: %s' % obj.__name__)
# Built-in functions cannot be inspected by
# inspect.getargspec. We have to try and parse
# the __doc__ attribute of the function.
docstr = obj.__doc__
args = ''
if docstr:
items = docstr.split('\n')
if items:
func_descr = items[0]
s = func_descr.replace(obj.__name__,'')
idx1 = s.find('(')
idx2 = s.find(')',idx1)
if idx1 != -1 and idx2 != -1 and (idx2>idx1+1):
args = s[idx1+1:idx2]
wi('\t-Method Arguments:', args)
if args=='':
wi('\t-Method Arguments: None')
print
def describe_func(obj, method=False):
""" Describe the function object passed as argument.
If this is a method object, the second argument will
be passed as True """
if method:
wi('+Method: %s' % obj.__name__)
else:
wi('+Function: %s' % obj.__name__)
try:
arginfo = inspect.getargspec(obj)
except TypeError:
print
return
args = arginfo[0]
argsvar = arginfo[1]
if args:
if args[0] == 'self':
wi('\t%s is an instance method' % obj.__name__)
args.pop(0)
wi('\t-Method Arguments:', args)
if arginfo[3]:
dl = len(arginfo[3])
al = len(args)
defargs = args[al-dl:al]
wi('\t--Default arguments:',zip(defargs, arginfo[3]))
if arginfo[1]:
wi('\t-Positional Args Param: %s' % arginfo[1])
if arginfo[2]:
wi('\t-Keyword Args Param: %s' % arginfo[2])
print
def describe_klass(obj):
""" Describe the class object passed as argument,
including its methods """
wi('+Class: %s' % obj.__name__)
indent()
count = 0
for name in obj.__dict__:
item = getattr(obj, name)
if inspect.ismethod(item):
count += 1;describe_func(item, True)
if count==0:
wi('(No members)')
dedent()
print
def describe(module):
""" Describe the module object passed as argument
including its classes and functions """
wi('[Module: %s]\n' % module.__name__)
indent()
count = 0
for name in dir(module):
obj = getattr(module, name)
if inspect.isclass(obj):
count += 1; describe_klass(obj)
elif (inspect.ismethod(obj) or inspect.isfunction(obj)):
count +=1 ; describe_func(obj)
elif inspect.isbuiltin(obj):
count += 1; describe_builtin(obj)
if count==0:
wi('(No members)')
dedent()
if __name__ == "__main__":
import sys
if len(sys.argv)<2:
sys.exit('Usage: %s <module>' % sys.argv[0])
module = sys.argv[1].replace('.py','')
mod = __import__(module)
describe(mod)
|
This came as a question in our local Python mailing list (BangPypers). I wrote up the above solution to provide a quick summary of a module in terms of classes, and simple method descriptions. The 'inspect' module makes this task relatively easy.
[Edit] - Added support for built-in functions/methods. [Edit 22/10/08] - Changes in printing style.
[Edited 28 Jul 2008, Anand]
I also found this useful in illustrating the use of indent and dedent in output. Make the output look pretty neat.
Wow. This is really helpful and cool.