273

I have a class Animal with several properties like:

 class Animal(object): def __init__(self): self.legs = 2 self.name = 'Dog' self.color= 'Spotted' self.smell= 'Alot' self.age = 10 self.kids = 0 #many more... 

I now want to print all these properties to a text file. The ugly way I'm doing it now is like:

 animal=Animal() output = 'legs:%d, name:%s, color:%s, smell:%s, age:%d, kids:%d' % (animal.legs, animal.name, animal.color, animal.smell, animal.age, animal.kids,) 

Is there a better Pythonic way to do this?

5
  • 1
    Did you try searching for questions related to locating all properties of a class? It's been asked. stackoverflow.com/questions/1215408/… for example. Commented May 11, 2011 at 19:52
  • 8
    @S.Lott: Although the OP asked specifically about properties of a class, from their example code I think it's fairly obvious they're not taking about data descriptors. Commented May 11, 2011 at 20:28
  • Relevant: stackoverflow.com/questions/1398022/… Commented Apr 24, 2016 at 13:43
  • Python offers the vars() function which returns a 'dictionary' of all the instance attributes along with their values. It is similar to the above methods, the only difference being, vars() focuses only on instance attributes and also returns their values along with them. Commented Sep 1, 2023 at 7:05
  • these are attributes of an instance, not a class Commented Dec 18, 2023 at 14:25

6 Answers 6

484

In this simple case you can use vars():

an = Animal() attrs = vars(an) # {'kids': 0, 'name': 'Dog', 'color': 'Spotted', 'age': 10, 'legs': 2, 'smell': 'Alot'} # now dump this in some way or another print(', '.join("%s: %s" % item for item in attrs.items())) 

If you want to store Python objects on the disk you should look at shelve — Python object persistence.

Sign up to request clarification or add additional context in comments.

7 Comments

Oh nice, never used vars like that! I thought it just acted like locals(), didn't know you could use it on a class/module. Very useful!
vars only works if you are using __dict__ to store the attributes (which is the default behaviour for Python objects). Refer to @BasicWolf's answer if you are using __slots__
Note that in this way you get unordered results. If you need to print for example in order of declaration, and you do not want to do it manually, check this
TypeError: vars() argument must have __dict__ attribute
Thanks but the name "BasicWolf" disappeared ... 😅 (possibly because of a renaming).
|
125

Another way is to call the dir() function (see https://docs.python.org/2/library/functions.html#dir).

a = Animal() dir(a) >>> ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'color', 'kids', 'legs', 'name', 'smell'] 

Note, that dir() tries to reach any attribute that is possible to reach.

Then you can access the attributes e.g. by filtering with double underscores:

attributes = [attr for attr in dir(a) if not attr.startswith('__')] 

This is just an example of what is possible to do with dir(), please check the other answers for proper way of doing this.

7 Comments

This is probably the right approach, but it should be pointed out that what it's doing is printing out the attributes, not the things called Properties in new-style classes in Python, and that it's doing it based on an instance of a class, not the class itself (because these attributes don't exist until the class instance is created and __init__() is called). Also if any other attributes are created later, they will be omitted, obviously.
Indeed. But I bet, it's really hard to teach one the overwhelming power of Python's dynamic constructions (objects, types, meta-classes, classes) unless one face them.
A better filtering (by user235925 on stackoverflow.com/questions/1398022/…) [attr for attr in dir(a) if not callable(getattr(Animal,attr)) and not attr.startswith("__")]
Works with @property as well
This is an fast and easy way to inspect any object, since an unfamiliar object may seem like a "dark box", you "unveil" its methods and attributes.
|
79

Maybe you are looking for something like this?

 >>> class MyTest: def __init__ (self): self.value = 3 >>> myobj = MyTest() >>> myobj.__dict__ {'value': 3} 

1 Comment

Note since this gives you a dictionary, you can also just look at the keys if you want a quick API reference print(o.__dict__.keys()).
11

try ppretty:

from ppretty import ppretty class Animal(object): def __init__(self): self.legs = 2 self.name = 'Dog' self.color= 'Spotted' self.smell= 'Alot' self.age = 10 self.kids = 0 print ppretty(Animal(), seq_length=10) 

Output:

__main__.Animal(age = 10, color = 'Spotted', kids = 0, legs = 2, name = 'Dog', smell = 'Alot') 

Comments

6

Here is full code. The result is exactly what you want.

class Animal(object): def __init__(self): self.legs = 2 self.name = 'Dog' self.color= 'Spotted' self.smell= 'Alot' self.age = 10 self.kids = 0 if __name__ == '__main__': animal = Animal() temp = vars(animal) for item in temp: print item , ' : ' , temp[item] #print item , ' : ', temp[item] , 

Comments

4

Just try beeprint

it prints something like this:

instance(Animal): legs: 2, name: 'Dog', color: 'Spotted', smell: 'Alot', age: 10, kids: 0, 

I think is exactly what you need.

3 Comments

If you're a SQLAlchemy user, this doesn't show your object's content properly.
@paulochf... please explain... just double checked...we're talking about python here and not SQL....
If the referred Python class is a SqlAlchemy model, one could want to print all of its attributes.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.