MyTetra Share
Делитесь знаниями!
Is there a built-in function to print all the current properties and values of an object?
Время создания: 16.07.2018 11:28
Текстовые метки: python pretty print object vars
Раздел: Python

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.


python debugging introspection pretty-print python-datamodel

shareimprove this question

edited Jun 19 '17 at 13:00


martineau

60.6k785158

asked Oct 10 '08 at 16:19


fuentesjr

19.7k256475

add a comment

22 Answers

active oldest votes

up vote

413

down vote

accepted

You are really mixing together two different things.


Use dir(), vars() or the inspect module to get what you are interested in (I use __builtins__ as an example; you can use any object instead).


>>> l = dir(__builtins__)

>>> d = __builtins__.__dict__

Print that dictionary however fancy you like:


>>> print l

['ArithmeticError', 'AssertionError', 'AttributeError',...

or


>>> from pprint import pprint

>>> pprint(l)

['ArithmeticError',

'AssertionError',

'AttributeError',

'BaseException',

'DeprecationWarning',

...


>>> pprint(d, indent=2)

{ 'ArithmeticError': <type 'exceptions.ArithmeticError'>,

'AssertionError': <type 'exceptions.AssertionError'>,

'AttributeError': <type 'exceptions.AttributeError'>,

...

'_': [ 'ArithmeticError',

'AssertionError',

'AttributeError',

'BaseException',

'DeprecationWarning',

...

Pretty printing is also available in the interactive debugger as a command:


(Pdb) pp vars()

{'__builtins__': {'ArithmeticError': <type 'exceptions.ArithmeticError'>,

'AssertionError': <type 'exceptions.AssertionError'>,

'AttributeError': <type 'exceptions.AttributeError'>,

'BaseException': <type 'exceptions.BaseException'>,

'BufferError': <type 'exceptions.BufferError'>,

...

'zip': <built-in function zip>},

'__file__': 'pass.py',

'__name__': '__main__'}

shareimprove this answer

edited May 4 '17 at 14:04

answered Oct 10 '08 at 17:27


hop

27.2k84960

13

Surprisingly, it seems not all objects have a __dict__ member (an re.MatchObject for instance), but builtin dir() works for all objects. – hobs Mar 18 '12 at 3:47

3

@hobs: cf. __slots__! – hop Mar 18 '12 at 18:46

print re.compile(r'slots').search('No slots here either.').__slots__ – hobs Mar 19 '12 at 1:40

2

New one to me. Thx. The dot triggered my brain's module path parser. Never even considered the Latin "module". – hobs Mar 20 '12 at 6:52

3

why don't you talk more about inspect module in your answer? I think it is the closest thing to print_r or var_dump. – Hai Phaikawl May 22 '12 at 10:56

show 1 more comment

up vote

722

down vote

You want vars() mixed with pprint():


from pprint import pprint

pprint(vars(your_object))

shareimprove this answer

edited Jun 9 '17 at 21:29


lmiguelvargasf

8,03796885

answered Oct 11 '08 at 1:16


Jeremy Cantrell

15.9k84574

41

most useful answer by far, and closest to PHP's print_r() as asked in the question – Noah Yetter Jun 27 '11 at 4:17

14

vars() simply returns the __dict__ of its argument and that is also the fallback of dir() in case there is no __dir__ method. so use dir() in the first place, as i said. – hop Dec 18 '11 at 20:16

21

@hop: dir() gives you all the built in things you probably don't care about like __str__ and __new__. var() doesn't. – Timmmm Jul 31 '12 at 17:23

14

If you're doing this in pdb, you don't need the import, just do pp vars(your_object) – wisbucky Jun 12 '14 at 18:35

7

This fails on sets and other objects that doesn't have __dict__ attribute. – anatoly techtonik Aug 24 '15 at 8:24

show 2 more comments

up vote

137

down vote

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.


shareimprove this answer

edited Jan 15 at 17:09

answered Oct 10 '08 at 16:36


Dan Lenski

44.9k95492

4

unpythonic, because follows not-invented-here – hop Oct 10 '08 at 17:31

13

Say what? Sure, you can use the getmembers() function in the standard inspect module, but I thought this would be more useful in that it illustrates how to do introspection in general. – Dan Lenski Oct 10 '08 at 17:44

18

NOT 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. – Dan Lenski Oct 10 '08 at 19:08

8

Some classes/objects don't contain any __dict__ attribute/member. I know it's crazy, but true. Built-ins like int and str or re.MatchObjects are common examples. Try 'hello'.__dict__, then try dir('hello') – hobs Mar 18 '12 at 4:50

2

Well, 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. – sdaau Nov 11 '13 at 0:27

show 6 more comments

up vote

35

down vote

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}

shareimprove this answer

edited Jul 28 '17 at 15:29


Vadim Kotov

3,95852947

answered Oct 10 '08 at 16:44


eduffy

28.5k87785

4

Objects like set doesn't have __dict__, so for them it will fail with AttributeError: 'set' object has no attribute '__dict__' – anatoly techtonik Aug 24 '15 at 8:27

add a comment

up vote

19

down vote

To print the current state of the object you might:


>>> obj # in an interpreter

or


print repr(obj) # in a script

or


print obj

For your classes define __str__ or __repr__ methods. From the Python documentation:


__repr__(self) Called by the repr() built-in function and by string conversions (reverse quotes) to compute the "official" string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form "<...some useful description...>" should be returned. The return value must be a string object. If a class defines repr() but not __str__(), then __repr__() is also used when an "informal" string representation of instances of that class is required. This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.


__str__(self) Called by the str() built-in function and by the print statement to compute the "informal" string representation of an object. This differs from __repr__() in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead. The return value must be a string object.


shareimprove this answer

answered Oct 11 '08 at 7:29


jfs

245k66506994

This option is useful for printing strings concatenated with the content of the object: print "DEBUG: object value: " + repr(obj) – AlejandroVD Nov 10 '15 at 15:27

add a comment

up vote

17

down vote

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

shareimprove this answer

edited Oct 10 '08 at 20:05


S.Lott

305k64426707

answered Oct 10 '08 at 16:20


Joe Skora

10.9k42935

add a comment

up vote

12

down vote

Might be worth checking out --


Is there a Python equivalent to Perl's Data::Dumper?


My recommendation is this --


https://gist.github.com/1071857


Note that perl has a module called Data::Dumper which translates object data back to perl source code (NB: it does NOT translate code back to source, and almost always you don't want to the object method functions in the output). This can be used for persistence, but the common purpose is for debugging.


There are a number of things standard python pprint fails to achieve, in particular it just stops descending when it sees an instance of an object and gives you the internal hex pointer of the object (errr, that pointer is not a whole lot of use by the way). 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.


The perl Data::Dumper allows you to control how deep you want to go, and also detects circular linked structures (that's really important). This process is fundamentally easier to achieve in perl because objects have no particular magic beyond their blessing (a universally well defined process).


shareimprove this answer

edited May 23 '17 at 10:31


Community♦

11

answered Nov 15 '12 at 4:11


Tel

12112

This should be a pip and a deb not only a gist! – phobie Aug 4 '15 at 18:27

2

> 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. – memeplex May 31 '16 at 0:21

add a comment

up vote

9

down vote

In most cases, using __dict__ or dir() will get you the info you're wanting. If you should happen to need more details, the standard library includes the inspect module, which allows you to get some impressive amount of detail. Some of the real nuggests of info include:


names of function and method parameters

class hierarchies

source code of the implementation of a functions/class objects

local variables out of a frame object

If you're just looking for "what attribute values does my object have?", then dir() and __dict__ are probably sufficient. If you're really looking to dig into the current state of arbitrary objects (keeping in mind that in python almost everything is an object), then inspect is worthy of consideration.


shareimprove this answer

edited Aug 24 '15 at 8:44


anatoly techtonik

11k58190

answered Oct 15 '08 at 14:53


William McVey

1282

Used your explanation on inspect to improve the most complete answer. Hope that's ok with you. – Fernando César Mar 11 at 19:34

add a comment

up vote

7

down vote

A metaprogramming example Dump object with magic:


$ cat dump.py

#!/usr/bin/python

import sys

if len(sys.argv) > 2:

module, metaklass = sys.argv[1:3]

m = __import__(module, globals(), locals(), [metaklass])

__metaclass__ = getattr(m, metaklass)


class Data:

def __init__(self):

self.num = 38

self.lst = ['a','b','c']

self.str = 'spam'

dumps = lambda self: repr(self)

__str__ = lambda self: self.dumps()


data = Data()

print data

Without arguments:


$ python dump.py

<__main__.Data instance at 0x00A052D8>

With Gnosis Utils:


$ python dump.py gnosis.magic MetaXMLPickler

<?xml version="1.0"?>

<!DOCTYPE PyObject SYSTEM "PyObjects.dtd">

<PyObject module="__main__" class="Data" id="11038416">

<attr name="lst" type="list" id="11196136" >

<item type="string" value="a" />

<item type="string" value="b" />

<item type="string" value="c" />

</attr>

<attr name="num" type="numeric" value="38" />

<attr name="str" type="string" value="spam" />

</PyObject>

It is a bit outdated but still working.


shareimprove this answer

edited Mar 28 '09 at 15:43

answered Oct 11 '08 at 7:53


jfs

245k66506994

add a comment

up vote

4

down vote

If you're using this for debugging, and you just want a recursive dump of everything, the accepted answer is unsatisfying because it requires that your classes have good __str__ implementations already. If that's not the case, this works much better:


import json

print(json.dumps(YOUR_OBJECT,

default=lambda obj: vars(obj),

indent=1))

shareimprove this answer

answered Nov 23 '14 at 21:20


Adam Cath

9912

this didn't work on python 3. Had to install pymongo and do it as per @Clark 's answer – Tim Ogilvy Apr 16 '15 at 8:04

Gives a circular reference error – dario_ramos Jul 25 '17 at 19:31

add a comment

up vote

3

down vote

I was needing to print DEBUG info in some logs and was unable to use pprint because it would break it. Instead I did this and got virtually the same thing.


DO = DemoObject()


itemDir = DO.__dict__


for i in itemDir:

print '{0} : {1}'.format(i, itemDir[i])

shareimprove this answer

answered Jun 28 '13 at 19:36


DaOneTwo

336

add a comment

up vote

3

down vote

To dump "myObject":


from bson import json_util

import json


print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': ')))

I tried vars() and dir(); both failed for what I was looking for. vars() didn't work because the object didn't have __dict__ (exceptions.TypeError: vars() argument must have __dict__ attribute). dir() wasn't what I was looking for: it's just a listing of field names, doesn't give the values or the object structure.


I think json.dumps() would work for most objects without the default=json_util.default, but I had a datetime field in the object so the standard json serializer failed. See How to overcome "datetime.datetime not JSON serializable" in python?


shareimprove this answer

edited May 23 '17 at 12:18


Community♦

11

answered Jun 26 '14 at 16:12


Clark

16413

is bson correct? – Tim Ogilvy Apr 16 '15 at 7:55

Okay yep had to install pymongo tho to use it. – Tim Ogilvy Apr 16 '15 at 8:09

add a comment

up vote

3

down vote

from pprint import pprint


def print_r(the_object):

print ("CLASS: ", the_object.__class__.__name__, " (BASE CLASS: ", the_object.__class__.__bases__,")")

pprint(vars(the_object))

shareimprove this answer

answered Jul 14 '14 at 15:01


32ndghost

311

Finally, something that actually worked. vars() was the key here – frostymarvelous Jul 14 '15 at 12:37

add a comment

up vote

3

down vote

Just try beeprint


it help you with not only printing object variables, but beautiful output, like this:


class(NormalClassNewStyle):

dicts: {

},

lists: [],

static_props: 1,

tupl: (1, 2)

shareimprove this answer

answered Sep 16 '16 at 16:12


Anyany Pan

35926

add a comment

up vote

2

down vote

pprint contains a “pretty printer” for producing aesthetically pleasing representations of your data structures. The formatter produces representations of data structures that can be parsed correctly by the interpreter, and are also easy for a human to read. The output is kept on a single line, if possible, and indented when split across multiple lines.


shareimprove this answer

answered Sep 13 '10 at 5:11


shahjapan

6,453145492

add a comment

up vote

2

down vote

This prints out all the object contents recursively in json or yaml indented format:


import jsonpickle # pip install jsonpickle

import json

import yaml # pip install pyyaml


serialized = jsonpickle.encode(obj, max_depth=2) # max_depth is optional

print json.dumps(json.loads(serialized), indent=4)

print yaml.dump(yaml.load(serialized), indent=4)

shareimprove this answer

edited Mar 5 '16 at 0:33

answered Mar 4 '16 at 19:32


wisbucky

7,96834747

add a comment

up vote

2

down vote

Try ppretty


from ppretty import ppretty



class A(object):

s = 5


def __init__(self):

self._p = 8


@property

def foo(self):

return range(10)



print ppretty(A(), show_protected=True, show_static=True, show_properties=True)

Output:


__main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5)

shareimprove this answer

answered Jul 28 '16 at 7:14


Symon

363312

add a comment

up vote

2

down vote

Why not something simple:


for key,value in obj.__dict__.iteritems():

print key,value

shareimprove this answer

edited Jul 28 '16 at 7:16


Paul Rooney

11.8k62442

answered Jun 14 '13 at 9:20


Michael Thamm

1096

Shouldn't that be for key,value in obj.__dict__.iteritems(): print key,value? – Raz Oct 30 '14 at 8:09

1

none of those are working for me – Tim Ogilvy Apr 16 '15 at 8:13

add a comment

up vote

2

down vote

I've upvoted the answer that mentions only pprint. To be clear, if you want to see all the values in a complex data structure, then do something like:


from pprint import pprint

pprint(my_var)

Where my_var is your variable of interest. When I used pprint(vars(my_var)) I got nothing, and other answers here didn't help or the method looked unnecessarily long. By the way, in my particular case, the code I was inspecting had a dictionary of dictionaries.


Worth pointing out that with some custom classes you may just end up with an unhelpful <someobject.ExampleClass object at 0x7f739267f400> kind of output. In that case, you might have to implement a __str__ method, or try some of the other solutions. I'd still like to find something simple that works in all scenarios, without third party libraries.


shareimprove this answer

edited Oct 9 '17 at 8:07

answered Sep 28 '17 at 4:35


Nagev

566614

>with some custom classes ... This is why I'm not a fan of python. Things "sometimes" work and "sometimes" not – AlxVallejo Dec 19 '17 at 15:09

add a comment

up vote

0

down vote

You can try the Flask Debug Toolbar.

https://pypi.python.org/pypi/Flask-DebugToolbar


from flask import Flask

from flask_debugtoolbar import DebugToolbarExtension


app = Flask(__name__)


# the toolbar is only enabled in debug mode:

app.debug = True


# set a 'SECRET_KEY' to enable the Flask session cookies

app.config['SECRET_KEY'] = '<replace with a secret key>'


toolbar = DebugToolbarExtension(app)

shareimprove this answer

answered Mar 7 '16 at 16:41


Slipstream

3,82112622

add a comment

up vote

0

down vote

I like working with python object built-in types keys or values.


For attributes regardless they are methods or variables:


o.keys()

For values of those attributes:


o.values()

shareimprove this answer

answered May 4 '17 at 12:53


Evhz

2,97222140

add a comment

up vote

0

down vote

For everybody struggling with


vars() not returning all attributes.

dir() not returning the attributes' values.

The following code prints all attributes of obj with their values:


for attr in dir(obj):

try:

print("obj.{} = {}".format(attr, getattr(obj, attr)))

except AttributeError:

print("obj.{} = ?".format(attr))

Так же в этом разделе:
 
MyTetra Share v.0.53
Яндекс индекс цитирования