Printing Object Attributes in Python

Content:

For debugging purposes, it can be incredibly useful to print out the attributes of an object. Python provides a few functions which you can use to do this.

Using vars()

The vars() method returns a dictionary, containing name-value pairs for each instance attribute defined in the given object.

class Car():
    def set_colour(self, colour: str):
        self.colour = colour

car = Car()
car.set_colour('red')

print(vars(car))    # {'colour': 'red'}

vars() returns the internal __dict__ attribute, which keeps track of the writable attributes attached to an object.

It’s important to understand that this function returns instance attributes – attributes defined in the class body, for example, will not be returned unless updated elsewhere.

class Car():
    wheels = 4

    def set_colour(self, colour: str):
        self.colour = colour

car = Car()
car.set_colour('red')

print(vars(car))    # {'colour': 'red'}

Note that in this example, the value for wheels is not returned, despite being defined for this object.

print(car.wheels)    # 4

__dict__ must be defined in the object for this to work, which it should be if you haven’t overridden any internally defined Python object methods. If __dict__ is undefined, vars() will throw a TypeError.

An alternative to using vars() is to call object.__dict__ directly. vars() reads from this itself, after all. It’s recommended to stick to vars(), though, as it’s a public function designed for this purpose.

Using dir()

dir() returns not only defined attributes, but also methods and objects defined in the passed object. This includes internally-defined methods.

Only the names of the attributes are returned.

class Car():
    def set_colour(self, colour: str):
        self.colour = colour

car = Car()
car.set_colour('red')

print(dir(car))    # ['__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__', '__str__', '__subclasshook__', '__weakref__', 'set_colour']

This means it does return attributes defined in the class body, unlike vars().

class Car():
    wheels = 4

    def set_colour(self, colour: str):
        self.colour = colour

car = Car()
car.set_colour('red')

print(dir(car))    # ['__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__', '__str__', '__subclasshook__', '__weakref__', 'set_colour', 'wheels']

To narrow the result to exclude built-in attributes, the output can be filtered. The following checks the first two characters for __, and excludes these values.

print([x for x in dir(car) if not x[:2] == '__'])
# ['set_colour', 'wheels']

Conclusion

This guide showed you two different ways to print out your object attributes. The output they produce is slightly different, so consider your requirements when choosing which to use.