Is there a built-in function to print all the current properties and values of an object?
Asked Answered
R

32

1485

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.

Reprobation answered 10/10, 2008 at 16:19 Comment(1)
You are asking for attributes, aren't you? The question is misleading, because property has a specific meaning in Python which differs from the meaning of attribute. If I am right, maybe you want to rephrase your question?Altitude
G
807

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__'}
Garfield answered 10/10, 2008 at 17:27 Comment(9)
Surprisingly, it seems not all objects have a __dict__ member (an re.MatchObject for instance), but builtin dir() works for all objects.Strainer
print re.compile(r'slots').search('No slots here either.').__slots__Strainer
@hobs: you are aware that "confer!" means "see also", "compare"? I know that match objects have no slots. that's not the point i tried to make.Garfield
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.Byer
The question isn't mixing two different things. The var function works as required: stackoverflow.com/posts/193539/revisionsNoncommittal
How do you access the values behind the attributes listed by dir(), then? dir() only returns a list of names, and not all of those exist in vars() or in the __dict__ attribute.Caveat
what do you mean "You are really mixing together two different things."?Trunnel
Regarding the inspect module: The method is inspect.getmembers, see also this answer.Carry
@Caveat Sorry its a long time reply - not everything listed by dir() is an attribute. And not everything is in the dict because of how slots work with optimised objects. But effectively, you can do a loop and do callable(object, varname) and if it's false, you can then do getattr on that to programmatically access. @tomasZubiri Vars() doesn't work always because of slots.Trioecious
S
1368

You want vars() mixed with pprint():

from pprint import pprint
pprint(vars(your_object))
Spohr answered 11/10, 2008 at 1:16 Comment(7)
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.Garfield
@hop: dir() gives you all the built in things you probably don't care about like __str__ and __new__. var() doesn't.Longdistance
This fails on sets and other objects that doesn't have __dict__ attribute.Flamsteed
this is absolutely good anwers, adding more: from inspect import getmembersLow
@hop, vars() gives the values of the fields, while dir() leaves them a mystery.Deafanddumb
str(pformat(vars(session)).encode('utf-8')).replace('\\n', '\n').replace('\\t', '\t') - dont kill me but with utf8 that what worksCaelian
if there are other objects in the properties you can use def nestvars(elem): if hasattr(elem, '__dict__'): return {k:nestvars(v) for (k,v) in vars(elem)} else: return elem and then nestvars(your_object)Freefloating
G
807

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__'}
Garfield answered 10/10, 2008 at 17:27 Comment(9)
Surprisingly, it seems not all objects have a __dict__ member (an re.MatchObject for instance), but builtin dir() works for all objects.Strainer
print re.compile(r'slots').search('No slots here either.').__slots__Strainer
@hobs: you are aware that "confer!" means "see also", "compare"? I know that match objects have no slots. that's not the point i tried to make.Garfield
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.Byer
The question isn't mixing two different things. The var function works as required: stackoverflow.com/posts/193539/revisionsNoncommittal
How do you access the values behind the attributes listed by dir(), then? dir() only returns a list of names, and not all of those exist in vars() or in the __dict__ attribute.Caveat
what do you mean "You are really mixing together two different things."?Trunnel
Regarding the inspect module: The method is inspect.getmembers, see also this answer.Carry
@Caveat Sorry its a long time reply - not everything listed by dir() is an attribute. And not everything is in the dict because of how slots work with optimised objects. But effectively, you can do a loop and do callable(object, varname) and if it's false, you can then do getattr on that to programmatically access. @tomasZubiri Vars() doesn't work always because of slots.Trioecious
C
306
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.

Casi answered 10/10, 2008 at 16:36 Comment(7)
unpythonic, because follows not-invented-hereGarfield
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.Casi
even then it sets a bad example, because you essentially reemplemented obj.__dict__ .Garfield
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.Casi
what are you talking about? both __module__ and __doc__ are in __dict__!Garfield
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')Strainer
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.Swamper
C
111

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}
Crinkleroot answered 10/10, 2008 at 16:44 Comment(1)
Objects like set doesn't have __dict__, so for them it will fail with AttributeError: 'set' object has no attribute '__dict__'Flamsteed
K
82

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.

Kaye answered 1/12, 2019 at 18:26 Comment(3)
pypi.org/project/beeprint (or github.com/panyanyany/beeprint) pretty prints 'everything' and also recursively.Deepseated
that what for parameters to get customized thing from a functionJesuit
@Deepseated not works for from collections import * ; obj=Counter([3,4])Jesuit
L
36

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
Lorraine answered 10/10, 2008 at 16:20 Comment(0)
I
27

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.

Iconoduly answered 11/10, 2008 at 7:29 Comment(1)
This option is useful for printing strings concatenated with the content of the object: print "DEBUG: object value: " + repr(obj)Neuralgia
U
21

I recommend using help(your_object).

help(dir)

 If called without an argument, return the names in the current scope.
 Else, return an alphabetized list of names comprising (some of) the attributes
 of the given object, and of attributes reachable from it.
 If the object supplies a method named __dir__, it will be used; otherwise
 the default dir() logic is used and returns:
 for a module object: the module's attributes.
 for a class object:  its attributes, and recursively the attributes
 of its bases.
 for any other object: its attributes, its class's attributes, and
 recursively the attributes of its class's base classes.

help(vars)

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.
Unbuild answered 7/12, 2018 at 10:49 Comment(0)
Q
20

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).

Quatrain answered 15/11, 2012 at 4:11 Comment(3)
> 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.Casiecasilda
@Casiecasilda where does it say python is all about OOP?Dress
this is only for 2.7Pleasurable
M
15

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.

Mofette answered 15/10, 2008 at 14:53 Comment(0)
O
13

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))
Onomatology answered 23/11, 2014 at 21:20 Comment(2)
this didn't work on python 3. Had to install pymongo and do it as per @Clark 's answerLaureenlaurel
as with many of the other answers here TypeError: vars() argument must have __dict__ attributeMessieurs
L
11

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)
Lek answered 28/7, 2016 at 7:14 Comment(1)
little 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 workingDiskin
I
9

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.

Iconoduly answered 11/10, 2008 at 7:53 Comment(0)
T
9

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)
Theca answered 4/3, 2016 at 19:32 Comment(1)
If you just want to serialize to a string, you don't even need jsonpickle: import yaml print(yaml.dump(your_object))Amundsen
C
7
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))
Cargill answered 14/7, 2014 at 15:1 Comment(0)
S
5

Why not something simple:

for key,value in obj.__dict__.iteritems():
    print key,value
Saum answered 14/6, 2013 at 9:20 Comment(2)
Shouldn't that be for key,value in obj.__dict__.iteritems(): print key,value?Ecclesiastic
Nice, suited. But fixed compile errors (maybe, other Python version) for key, value in params.__dict__.items(): print(key + " = " + str(value))Fusil
S
5

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 also found that in one instance where I got this object type of output, vars() showed me what I wanted. So a better solution to cover both cases would be to try both individually. But using vars() can sometimes throw an exception, for example, TypeError: vars() argument must have __dict__ attribute.

I'd still like to find something simple that works in all scenarios, without third party libraries.

Shiest answered 28/9, 2017 at 4:35 Comment(0)
G
5

This works no matter how your varibles are defined within a class, inside __init__ or outside.

your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}
Gunzburg answered 3/2, 2020 at 4:43 Comment(2)
Addition to exclude all built-in vars (methods, functions etc) : {attr: getattr(your_obj, attr) for attr in dir(your_obj) and "__" not in attr}Aquino
@Aquino I get a syntax error with your version ""attr" is not defined"Theisen
S
4

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])
Sanative answered 28/6, 2013 at 19:36 Comment(0)
F
4

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?

Fruiterer answered 26/6, 2014 at 16:12 Comment(1)
Okay yep had to install pymongo tho to use it.Laureenlaurel
H
3

Just try beeprint.

It will help you not only with printing object variables, but beautiful output as well, like this:

class(NormalClassNewStyle):
  dicts: {
  },
  lists: [],
  static_props: 1,
  tupl: (1, 2)
Heulandite answered 16/9, 2016 at 16:12 Comment(2)
This module does not seemed to be maintained any more and have a number of open issues. Rather use pprettyToplevel
beeprint is too verbose, can't figure out how to exclude e.g. properties starting with _ etc. Not documented very well - or maintained.Theisen
E
3

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))
Edema answered 7/9, 2017 at 11:40 Comment(1)
get no errors, but not recursive so just get a lot of hex addressesMessieurs
D
2

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.

Dirk answered 13/9, 2010 at 5:11 Comment(0)
M
2

While there are many good answers, here is a 1-liner that can give the attributes AS WELL AS values:

(str(vars(config)).split(",")[1:])

where 'config' is the object in question. I am listing this as a separate answer because I just wanted to simply print the relevant values of the object (excl the __main etc) without using loops or pretty print and didn't find a convenient answer.

Multiracial answered 4/10, 2021 at 8:4 Comment(0)
S
1

This project modifies pprint to show all object field values, it ignores he objects __repr__ member function, it also recurses into nested objects. It works with python3, see https://github.com/MoserMichael/pprintex You can install it via pip: pip install printex

Saiga answered 15/9, 2021 at 2:4 Comment(0)
G
1

vars() seems to show the attributes of this object, but dir() seems to show attributes of parent class(es) as well. You don't usually need to see inherited attributes such as str, doc. dict etc.

In [1]: class Aaa():
...:     def __init__(self, name, age):
...:         self.name = name
...:         self.age = age
...:
In [2]: class Bbb(Aaa):
...:     def __init__(self, name, age, job):
...:         super().__init__(name, age)
...:         self.job = job
...:
In [3]: a = Aaa('Pullayya',42)

In [4]: b = Bbb('Yellayya',41,'Cop')

In [5]: vars(a)
Out[5]: {'name': 'Pullayya', 'age': 42}

In [6]: vars(b)
Out[6]: {'name': 'Yellayya', 'age': 41, 'job': 'Cop'}

In [7]: dir(a)
Out[7]:
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 ...
 ...
 '__subclasshook__',
 '__weakref__',
 'age',
 'name']
Glottic answered 18/12, 2021 at 12:18 Comment(0)
I
1

@dataclass + pprint (recursive, indented, no external libs, Python 3.10)

@dataclass is just amazing, and pprint from Python 3.10 learnt to print dataclasses with indentation, so if you can convert your code to @dataclass this is a very good approach:

from dataclasses import dataclass
from pprint import pprint

@dataclass
class MyClass1:
    s: str
    n0: int
    n1: int
    n2: int
    n3: int
    n4: int
    n5: int
    n6: int
    n7: int
    n8: int
    n9: int

@dataclass
class MyClass2:
    s: str
    n0: int
    n1: int
    n2: int
    n3: int
    n4: int
    n5: int
    n6: int
    n7: int
    n8: int
    n9: int
    my_class_1: MyClass1

obj = MyClass2(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9, my_class_1=MyClass1(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9))
print(obj)
pprint(obj)

Output:

MyClass2(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9, my_class_1=MyClass1(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9))
MyClass2(s='a',
         n0=0,
         n1=1,
         n2=2,
         n3=3,
         n4=4,
         n5=5,
         n6=6,
         n7=7,
         n8=8,
         n9=9,
         my_class_1=MyClass1(s='a',
                             n0=0,
                             n1=1,
                             n2=2,
                             n3=3,
                             n4=4,
                             n5=5,
                             n6=6,
                             n7=7,
                             n8=8,
                             n9=9))

See also: Pretty-print dataclasses prettier with line breaks and indentation

@dataclass also gives you other very good features for free:

Vs other answers

Let's create a comparable non @dataclass code

from pprint import pprint

class MyClass1:
    def __init__(self, s, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9):
        self.s = s
        self.n0 = n0
        self.n1 = n1
        self.n2 = n2
        self.n3 = n3
        self.n4 = n4
        self.n5 = n5
        self.n6 = n6
        self.n7 = n7
        self.n8 = n8
        self.n9 = n9

class MyClass2:
    def __init__(self, s, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, my_class_1):
        self.s = s
        self.n0 = n0
        self.n1 = n1
        self.n2 = n2
        self.n3 = n3
        self.n4 = n4
        self.n5 = n5
        self.n6 = n6
        self.n7 = n7
        self.n8 = n8
        self.n9 = n9
        self.n9 = n9
        self.my_class_1 = my_class_1

obj = MyClass2(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9, my_class_1=MyClass1(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9))
pprint(vars(obj))

pprint(vars(obj)) output is non-recursive:

{'my_class_1': <__main__.MyClass1 object at 0x7fee21a9bf70>,
 'n0': 0,
 'n1': 1,
 'n2': 2,
 'n3': 3,
 'n4': 4,
 'n5': 5,
 'n6': 6,
 'n7': 7,
 'n8': 8,
 'n9': 9,
 's': 'a'}

Tested on Python 3.10.7, Ubuntu 22.10.

Ingle answered 20/4, 2023 at 7:9 Comment(0)
I
0

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)
Interim answered 7/3, 2016 at 16:41 Comment(0)
V
0

From the answer, it can be slightly modified to get only 'Attributes' of an object as below:

def getAttributes(obj):
    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 for name in dir(obj) 
            if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}
    pprint(attributes(obj))

It is helpful when adding this function temporary and can be removed without many changes in existing source code

Verity answered 18/8, 2021 at 5:41 Comment(0)
A
0

I have not tested performance, but I believe this is the fastest method to enumerate just the properties / attributes / keys of any object in Python as a list.

# If core==False, ignore __k__ entries
def obj_props(obj, core=False) -> list:
    assert not obj is None, f"obj must not be null (None)"
    _props = []
    _use_dir=False
    def _add(p):
        if not core and p.find('__') == 0: return
        _props.append(p)
    if hasattr(obj, '__dict__'): 
        for p in obj.__dict__.keys(): _add(p)
    elif hasattr(obj, '__slots__'):
        for p in obj.__slots__: _add(p)
    elif hasattr(obj, 'keys'):
        try:
            for p in obj.keys(): _add(p)
        except Exception as ex:
            _props = []
            _use_dir = True
    else:
        _use_dir = True
    if _use_dir:
        # fall back to slow and steady
        for p in dir(obj):
            if not core and p.find('__') == 0: continue
            v = getattr(obj, p)
            v_t = type(v).__name__
            if v_t in ('function', 'method', 'builtin_function_or_method', 'method-wrapper'): continue
            _props.append(p)

    return _props

The above should work with regular python objects (with __dict__), objects using slots (__slots__) and even work with dictionary like objects.

Most other examples utilize dir(obj) which will enumerate all methods and properties of an object which will take a performance hit if you only need its properties.

Abeokuta answered 11/10, 2022 at 17:5 Comment(0)
S
0

I wanted to var_dump / print_r the browser state of Selenium, but some of its class properties are not always implemented / accessible (depending on the browser used), which causes exceptions in some cases. None of the solutions posted so far seemed to be able to work around that problem, so I was unable to dump all properties before things crashed. This is the only clean solution I could come up with:

import warnings

def dump(obj):
  for name in dir(obj):
    e = False
    with warnings.catch_warnings():
      warnings.simplefilter("ignore")
      try:
        v = getattr(obj, name)
      except:
        e = True
      warnings.simplefilter("default")
    if not e:
      print("obj.%s = %r" % (name, v))
    else:
      print("<inaccessible property obj.%s>" % name)

This also suppresses warnings (e.g. deprecations) upon accessing properties. Note that it is not recursive.

Sleepyhead answered 8/10, 2023 at 4:7 Comment(0)
C
-1

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()
Center answered 4/5, 2017 at 12:53 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.