str()
and repr()
can be used to print the contents of a variable in python. But the contents of a variable may be quite complex. The pprint
library, reported as the php var_dump()
equivalent, works nicely for displaying just data in an easy to read format: What is a Python equivalent of PHP's var_dump()?, Is there a function in Python to print all the current properties and values of an object?
However if there are objects in the data ([edit] that haven't implemented __str__
or __repr__
), str()
, repr()
and pprint
just gives their names. I'd like a method that can recursively walk through objects' attributes too, properly giving the entire representation of a variable.
Certain functions such as builtins shouldn't be printed as it's not useful. The method should also be able to handle issues such as getattr
throwing exceptions. Perhaps custom iterables could also be handled the same way as lists.
I've given it a shot below. Not that it doesn't work, but I'm sure there are edge cases not accounted for and probably some missing information from the output (e.g. distinguish tuples/lists). What I mean to say is, please share alternatives :)
To print the attributes of an object we can use “object. __dict__” and it return a dictionary of all names and attributes of object.
How to Print the Type of a Variable in Python. To get the type of a variable in Python, you can use the built-in type() function. In Python, everything is an object. So, when you use the type() function to print the type of the value stored in a variable to the console, it returns the class type of the object.
Python getattr() function. Python getattr() function is used to get the value of an object's attribute and if no attribute of that object is found, default value is returned. Basically, returning the default value is the main reason why you may need to use Python getattr() function.
This prints out all the object contents recursively in json or yaml (take your pick) indented format:
import jsonpickle # pip install jsonpickle
import json
import yaml # pip install pyyaml
serialized = jsonpickle.encode(obj)
print json.dumps(json.loads(serialized), indent=4)
print yaml.dump(yaml.load(serialized), indent=4)
Here's my answer. This works pretty well for my purposes, but again, I'm sure there are more robust ways to do this. If you have a better way, please share it :)
import types
def var_dump(obj, depth=4, l=""):
#fall back to repr
if depth<0: return repr(obj)
#expand/recurse dict
if isinstance(obj, dict):
name = ""
objdict = obj
else:
#if basic type, or list thereof, just print
canprint=lambda o:isinstance(o, (int, float, str, unicode, bool, types.NoneType, types.LambdaType))
try:
if canprint(obj) or sum(not canprint(o) for o in obj) == 0: return repr(obj)
except TypeError, e:
pass
#try to iterate as if obj were a list
try:
return "[\n" + "\n".join(l + var_dump(k, depth=depth-1, l=l+" ") + "," for k in obj) + "\n" + l + "]"
except TypeError, e:
#else, expand/recurse object attribs
name = (hasattr(obj, '__class__') and obj.__class__.__name__ or type(obj).__name__)
objdict = {}
for a in dir(obj):
if a[:2] != "__" and (not hasattr(obj, a) or not hasattr(getattr(obj, a), '__call__')):
try: objdict[a] = getattr(obj, a)
except Exception, e: objdict[a] = str(e)
return name + "{\n" + "\n".join(l + repr(k) + ": " + var_dump(v, depth=depth-1, l=l+" ") + "," for k, v in objdict.iteritems()) + "\n" + l + "}"
Example output:
class B(object):
mystatic = [1,2,3]
class A:
mystatic = "hello"
def __init__(self):
self.mymember1 = B()
self.mymember2 = B(), 123.4, "world"
def myfunc(self):
print "hi"
var = {"foo": A(), "bar": B()}
...
>>> print var_dump(var)
{
'foo': A{
'mystatic': 'hello',
'mymember1': B{
'mystatic': [1, 2, 3],
},
'mymember2': [
B{
'mystatic': [1, 2, 3],
},
123.4,
'world',
],
},
'bar': B{
'mystatic': [1, 2, 3],
},
}
I originally wrote this because django's debug toolbar used pprint
and was only showing first level data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With