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.
