Print a nicely formatted overview of an object, including _everything_ in the object's `dir'. This is great when programming interactively.
More comprehensive than help(), prettier than dir().
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 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | def printDict(di, format="%-25s %s"):
for (key, val) in di.items():
print format % (str(key)+':', val)
def dumpObj(obj, maxlen=77, lindent=24, maxspew=600):
"""Print a nicely formatted overview of an object.
The output lines will be wrapped at maxlen, with lindent of space
for names of attributes. A maximum of maxspew characters will be
printed for each attribute value.
You can hand dumpObj any data type -- a module, class, instance,
new class.
Note that in reformatting for compactness the routine trashes any
formatting in the docstrings it prints.
Example:
>>> class Foo(object):
a = 30
def bar(self, b):
"A silly method"
return a*b
... ... ... ...
>>> foo = Foo()
>>> dumpObj(foo)
Instance of class 'Foo' as defined in module __main__ with id 136863308
Documentation string: None
Built-in Methods: __delattr__, __getattribute__, __hash__, __init__
__new__, __reduce__, __repr__, __setattr__,
__str__
Methods:
bar "A silly method"
Attributes:
__dict__ {}
__weakref__ None
a 30
"""
import types
# Formatting parameters.
ltab = 2 # initial tab in front of level 2 text
# There seem to be a couple of other types; gather templates of them
MethodWrapperType = type(object().__hash__)
#
# Gather all the attributes of the object
#
objclass = None
objdoc = None
objmodule = '<None defined>'
methods = []
builtins = []
classes = []
attrs = []
for slot in dir(obj):
attr = getattr(obj, slot)
if slot == '__class__':
objclass = attr.__name__
elif slot == '__doc__':
objdoc = attr
elif slot == '__module__':
objmodule = attr
elif (isinstance(attr, types.BuiltinMethodType) or
isinstance(attr, MethodWrapperType)):
builtins.append( slot )
elif (isinstance(attr, types.MethodType) or
isinstance(attr, types.FunctionType)):
methods.append( (slot, attr) )
elif isinstance(attr, types.TypeType):
classes.append( (slot, attr) )
else:
attrs.append( (slot, attr) )
#
# Organize them
#
methods.sort()
builtins.sort()
classes.sort()
attrs.sort()
#
# Print a readable summary of those attributes
#
normalwidths = [lindent, maxlen - lindent]
tabbedwidths = [ltab, lindent-ltab, maxlen - lindent - ltab]
def truncstring(s, maxlen):
if len(s) > maxlen:
return s[0:maxlen] + ' ...(%d more chars)...' % (len(s) - maxlen)
else:
return s
# Summary of introspection attributes
if objclass == '':
objclass = type(obj).__name__
intro = "Instance of class '%s' as defined in module %s with id %d" % \
(objclass, objmodule, id(obj))
print '\n'.join(prettyPrint(intro, maxlen))
# Object's Docstring
if objdoc is None:
objdoc = str(objdoc)
else:
objdoc = ('"""' + objdoc.strip() + '"""')
print
print prettyPrintCols( ('Documentation string:',
truncstring(objdoc, maxspew)),
normalwidths, ' ')
# Built-in methods
if builtins:
bi_str = delchars(str(builtins), "[']") or str(None)
print
print prettyPrintCols( ('Built-in Methods:',
truncstring(bi_str, maxspew)),
normalwidths, ', ')
# Classes
if classes:
print
print 'Classes:'
for (classname, classtype) in classes:
classdoc = getattr(classtype, '__doc__', None) or '<No documentation>'
print prettyPrintCols( ('',
classname,
truncstring(classdoc, maxspew)),
tabbedwidths, ' ')
# User methods
if methods:
print
print 'Methods:'
for (methodname, method) in methods:
methoddoc = getattr(method, '__doc__', None) or '<No documentation>'
print prettyPrintCols( ('',
methodname,
truncstring(methoddoc, maxspew)),
tabbedwidths, ' ')
# Attributes
if attrs:
print
print 'Attributes:'
for (attr, val) in attrs:
print prettyPrintCols( ('',
attr,
truncstring(str(val), maxspew)),
tabbedwidths, ' ')
def prettyPrintCols(strings, widths, split=' '):
"""Pretty prints text in colums, with each string breaking at
split according to prettyPrint. margins gives the corresponding
right breaking point."""
assert len(strings) == len(widths)
strings = map(nukenewlines, strings)
# pretty print each column
cols = [''] * len(strings)
for i in range(len(strings)):
cols[i] = prettyPrint(strings[i], widths[i], split)
# prepare a format line
format = ''.join(["%%-%ds" % width for width in widths[0:-1]]) + "%s"
def formatline(*cols):
return format % tuple(map(lambda s: (s or ''), cols))
# generate the formatted text
return '\n'.join(map(formatline, *cols))
def prettyPrint(string, maxlen=75, split=' '):
"""Pretty prints the given string to break at an occurrence of
split where necessary to avoid lines longer than maxlen.
This will overflow the line if no convenient occurrence of split
is found"""
# Tack on the splitting character to guarantee a final match
string += split
lines = []
oldeol = 0
eol = 0
while not (eol == -1 or eol == len(string)-1):
eol = string.rfind(split, oldeol, oldeol+maxlen+len(split))
lines.append(string[oldeol:eol])
oldeol = eol + len(split)
return lines
def nukenewlines(string):
"""Strip newlines and any trailing/following whitespace; rejoin
with a single space where the newlines were.
Bug: This routine will completely butcher any whitespace-formatted
text."""
if not string: return ''
lines = string.splitlines()
return ' '.join( [line.strip() for line in lines] )
def delchars(str, chars):
"""Returns a string for which all occurrences of characters in
chars have been removed."""
# Translate demands a mapping string of 256 characters;
# whip up a string that will leave all characters unmolested.
identity = ''.join([chr(x) for x in range(256)])
return str.translate(identity, chars)
|
Often -- especially for extension types written in C -- the output of help is un-help-ful. You can run 'dir(a)' to find the attributes of an object 'a', and then sift through the attributes to find what you want... or you can run dumpObj!
See the docstring for output from dumpObj on a silly example class. For real fun, run it on modules or your own data structures.
============================= Documentation: ================================
Print a nicely formatted overview of an object.
You can hand dumpObj any data type -- a module, class, instance, new class.
The output lines will be wrapped at maxlen, with lindent of space for names of attributes. A maximum of maxspew characters will be printed for each attribute value. Note that in reformatting for compactness the routine trashes any formatting in the docstrings it prints.
Please note: Some version 2.2 features used. Please note that in addition to many other v2.0+ features, this routine uses the new python v2.2 feature of nested local scopes; if you have an older version you may need to change
to a lambda statement or use the format=format default-parameter stunt.
Parameters of a method.... ..... Is there an easy way from Python to tell what parameters line up with a method? Would one call a (dir) on the method?
Just curious...
Signatures. See the signature.py module written by Neel Krishnaswami at
The Signature class it defines allows you to determine what parameters a method (or other callable) takes.
There are number of other interesting modules to check out there, too.
What stunt? I need to rewrite your lovely dumpObj to work with python2.1 but I don't understand the formatline() method. Some more hints maybe?
Missing unicode support. This code is great, but it does not support unicode values in the __dict__.
Please change line 152 from