Created
January 30, 2013 05:55
-
-
Save sunilmallya/4671033 to your computer and use it in GitHub Desktop.
dumpObject
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Dump python object | |
@author: Not sure, had this code snippet, happy to attribute to who wrote this, saving for personal use | |
""" | |
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 prettyPrintCols( ('Documentation string:', | |
truncstring(objdoc, maxspew)), | |
normalwidths, ' ') | |
# Built-in methods | |
if builtins: | |
bi_str = delchars(str(builtins), "[']") or str(None) | |
print prettyPrintCols( ('Built-in Methods:', | |
truncstring(bi_str, maxspew)), | |
normalwidths, ', ') | |
# Classes | |
if classes: | |
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 '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 '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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment