Is there a built-in function to print all the current properties and values of an object?
Solution 1
You want vars()
mixed with pprint()
:
from pprint import pprint
pprint(vars(your_object))
Solution 2
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
There are many 3rd-party functions out there that add things like exception handling, national/special character printing, recursing into nested objects etc. according to their authors' preferences. But they all basically boil down to this.
Solution 3
dir has been mentioned, but that'll only give you the attributes' names. If you want their values as well try __dict__.
class O:
def __init__ (self):
self.value = 3
o = O()
Here is the output:
>>> o.__dict__
{'value': 3}
Solution 4
Is there a built-in function to print all the current properties and values of an object?
No. The most upvoted answer excludes some kinds of attributes, and the accepted answer shows how to get all attributes, including methods and parts of the non-public api. But there is no good complete builtin function for this.
So the short corollary is that you can write your own, but it will calculate properties and other calculated data-descriptors that are part of the public API, and you might not want that:
from pprint import pprint
from inspect import getmembers
from types import FunctionType
def attributes(obj):
disallowed_names = {
name for name, value in getmembers(type(obj))
if isinstance(value, FunctionType)}
return {
name: getattr(obj, name) for name in dir(obj)
if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}
def print_attributes(obj):
pprint(attributes(obj))
Problems with other answers
Observe the application of the currently top voted answer on a class with a lot of different kinds of data members:
from pprint import pprint
class Obj:
__slots__ = 'foo', 'bar', '__dict__'
def __init__(self, baz):
self.foo = ''
self.bar = 0
self.baz = baz
@property
def quux(self):
return self.foo * self.bar
obj = Obj('baz')
pprint(vars(obj))
only prints:
{'baz': 'baz'}
Because vars
only returns the __dict__
of an object, and it's not a copy, so if you modify the dict returned by vars, you're also modifying the __dict__
of the object itself.
vars(obj)['quux'] = 'WHAT?!'
vars(obj)
returns:
{'baz': 'baz', 'quux': 'WHAT?!'}
-- which is bad because quux is a property that we shouldn't be setting and shouldn't be in the namespace...
Applying the advice in the currently accepted answer (and others) is not much better:
>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bar', 'baz', 'foo', 'quux']
As we can see, dir
only returns all (actually just most) of the names associated with an object.
inspect.getmembers
, mentioned in the comments, is similarly flawed - it returns all names and values.
From class
When teaching I have my students create a function that provides the semantically public API of an object:
def api(obj):
return [name for name in dir(obj) if name[0] != '_']
We can extend this to provide a copy of the semantic namespace of an object, but we need to exclude __slots__
that aren't assigned, and if we're taking the request for "current properties" seriously, we need to exclude calculated properties (as they could become expensive, and could be interpreted as not "current"):
from types import FunctionType
from inspect import getmembers
def attrs(obj):
disallowed_properties = {
name for name, value in getmembers(type(obj))
if isinstance(value, (property, FunctionType))
}
return {
name: getattr(obj, name) for name in api(obj)
if name not in disallowed_properties and hasattr(obj, name)
}
And now we do not calculate or show the property, quux:
>>> attrs(obj)
{'bar': 0, 'baz': 'baz', 'foo': ''}
Caveats
But perhaps we do know our properties aren't expensive. We may want to alter the logic to include them as well. And perhaps we want to exclude other custom data descriptors instead.
Then we need to further customize this function. And so it makes sense that we cannot have a built-in function that magically knows exactly what we want and provides it. This is functionality we need to create ourselves.
Conclusion
There is no built-in function that does this, and you should do what is most semantically appropriate for your situation.
Solution 5
You can use the "dir()" function to do this.
>>> import sys
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdo
t__', '_current_frames', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder
, 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'exc_clear', 'exc_info'
'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval', 'getdefault
ncoding', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getwindowsversion', 'he
version', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_
ache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'setrecursionlimit
, 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoption
', 'winver']
>>>
Another useful feature is help.
>>> help(sys)
Help on built-in module sys:
NAME
sys
FILE
(built-in)
MODULE DOCS
http://www.python.org/doc/current/lib/module-sys.html
DESCRIPTION
This module provides access to some objects used or maintained by the
interpreter and to functions that interact strongly with the interpreter.
Dynamic objects:
argv -- command line arguments; argv[0] is the script pathname if known
Comments
-
fuentesjr over 2 years
So what I'm looking for here is something like PHP's print_r function.
This is so I can debug my scripts by seeing what's the state of the object in question.
-
Admin over 15 yearsunpythonic, because follows not-invented-here
-
Dan Lenski over 15 yearsSay what? Sure, you can use the
getmembers()
function in the standardinspect
module, but I thought this would be more useful in that it illustrates how to do introspection in general. -
Admin over 15 yearseven then it sets a bad example, because you essentially reemplemented obj.__dict__ .
-
Dan Lenski over 15 yearsNOT AT ALL. dir(obj) shows properties that aren't found in
__dict__
(such as__doc__
and__module__
). Furthermore,__dict__
doesn't work at all for objects declared with__slots__
. In general,__dict__
shows user-level properties that are actually stored in a dictionary internally. dir() shows more. -
Admin over 15 yearswhat are you talking about? both
__module__
and__doc__
are in__dict__
! -
Admin over 12 years
vars()
simply returns the__dict__
of its argument and that is also the fallback ofdir()
in case there is no__dir__
method. so usedir()
in the first place, as i said. -
hobs over 12 yearsSome classes/objects don't contain any
__dict__
attribute/member. I know it's crazy, but true. Built-ins likeint
andstr
orre.MatchObject
s are common examples. Try'hello'.__dict__
, then trydir('hello')
-
Timmmm almost 12 years@hop:
dir()
gives you all the built in things you probably don't care about like__str__
and__new__
.var()
doesn't. -
sdaau over 10 yearsWell, this answer at least prints both attributes' names and values, in case an object doesn't have a dict (like the return from, say,
QtGui.QMdiSubWindow.sizePolicy()
), which is what I like about it. -
port5432 about 10 yearsI like the vars/pprint option above, but this is good as it does not require inclusion of an libraries.
-
Raz over 9 yearsShouldn't that be
for key,value in obj.__dict__.iteritems(): print key,value
? -
Tim Ogilvy about 9 yearsthis didn't work on python 3. Had to install pymongo and do it as per @Clark 's answer
-
Tim Ogilvy about 9 yearsOkay yep had to install pymongo tho to use it.
-
phobie almost 9 yearsThis should be a pip and a deb not only a gist!
-
anatoly techtonik almost 9 yearsThis fails on sets and other objects that doesn't have
__dict__
attribute. -
anatoly techtonik almost 9 yearsObjects like
set
doesn't have__dict__
, so for them it will fail withAttributeError: 'set' object has no attribute '__dict__'
-
AlejandroVD over 8 yearsThis option is useful for printing strings concatenated with the content of the object:
print "DEBUG: object value: " + repr(obj)
-
memeplex about 8 years> So in a nutshell, python is all about this great object oriented paradigm, but the tools you get out of the box are designed for working with something other than objects... Quite a claim when the only example you're providing is a module of secondary importance.
-
Jordan almost 7 yearsLOL Tenable use this in their Nessus python library (see the objdump function) github.com/tenable/nessrest/blob/…
-
Dan Lenski almost 7 yearsIndeed… verbatim! Wow :-D github.com/tenable/nessrest/blob/…
-
AlxVallejo over 6 years>with some custom classes ... This is why I'm not a fan of python. Things "sometimes" work and "sometimes" not
-
hidefromkgb over 6 yearsI do not care whether that`s «unpythonic» or whatnot. It gets the job done, which in debugging is the one and only thing that matters.
-
Fernando César over 6 yearsUsed your explanation on inspect to improve the most complete answer. Hope that's ok with you.
-
Peter Wood over 5 years@memeplex where does it say python is all about OOP?
-
memeplex over 5 yearsOk, it just says it's all about this great OOP, my bad.
-
Wavesailor over 5 yearsThis module does not seemed to be maintained any more and have a number of open issues. Rather use ppretty
-
rob over 4 yearsas with many of the other answers here
TypeError: vars() argument must have __dict__ attribute
-
rob over 4 yearsget no errors, but not recursive so just get a lot of hex addresses
-
Joseph Astrahan over 4 yearsexactly what I was looking for for quick debug :), great find!
-
Joseph Astrahan over 4 yearslittle hint add depth=6 (or however far you need) as one of the parameters for it and the recursion details can go further :). One of the things I like about how it prints lists is it shows the first 2 entires and last 2 entries so you know it's working
-
Rainb about 4 yearsthis is only for 2.7
-
Basil Musa almost 4 yearsThe best answer so far. To hell with "unpythonic" approaches : )))
-
joe-khoa over 3 yearsthis is absolutely good anwers, adding more: from inspect import getmembers
-
cowlinator over 3 years@hop,
vars()
gives the values of the fields, whiledir()
leaves them a mystery. -
Sion C almost 3 yearsstr(pformat(vars(session)).encode('utf-8')).replace('\\n', '\n').replace('\\t', '\t') - dont kill me but with utf8 that what works
-
NZD almost 3 yearspypi.org/project/beeprint (or github.com/panyanyany/beeprint) pretty prints 'everything' and also recursively.
-
Smart Manoj almost 3 yearsthat what for parameters to get customized thing from a function
-
Smart Manoj almost 3 years@NZD not works for
from collections import * ; obj=Counter([3,4])
-
Vladimir over 2 yearsAddition to exclude all built-in vars (methods, functions etc) :
{attr: getattr(your_obj, attr) for attr in dir(your_obj) and "__" not in attr}
-
ejkitchen over 2 yearsThis is the most comprehensive answer and should be upvoted more
-
TCSGrad over 2 yearsHoly eff, THIS is the answer i was looking for. Why it isnt the accepted answer, i'll never know.
-
Admin about 2 yearsNice, suited. But fixed compile errors (maybe, other Python version) for key, value in params.__dict__.items(): print(key + " = " + str(value))