Print All Object Attributes in Python (Works With Slots)

The best way to get all object attributes in Python is to use the built-in dir() function. This function returns a list of all of the object’s attribute names, including inherited ones:

print(dir(my_dog)) # Output: ['__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__', 'age', 'breed', 'name']
Code language: Python (python)

And notably it works with objects that implement __slots__.

We can combine this with a dictionary comprehension to get all of the attributes and values for an object:

pprint.pprint({attr: getattr(my_dog, attr) for attr in dir(my_dog)}) """ Output: {'__class__': <class '__main__.Dog'>, '__delattr__': <method-wrapper '__delattr__' of Dog object at 0x7f8d724628b0>, '__dict__': {'age': 3, 'breed': 'Labrador', 'name': 'Fido'}, ...SNIPPED... '__str__': <method-wrapper '__str__' of Dog object at 0x7f8d724628b0>, '__subclasshook__': <built-in method __subclasshook__ of type object at 0x1e733b0>, '__weakref__': None, 'age': 3, 'breed': 'Labrador', 'name': 'Fido'} """
Code language: Python (python)

This will print all of an object’s attributes and values, including its inherited ones.

Here is an example showing an object that uses __slots__:

class Foo: __slots__ = ['bar'] def __init__(self, bar): self.bar = bar foo = Foo('baz') pprint.pprint({attr: getattr(foo, attr) for attr in dir(foo)}) """ Output: {'__class__': <class '__main__.Foo'>, '__delattr__': <method-wrapper '__delattr__' of Foo object at 0x7f8d71a8c580>, '__dir__': <built-in method __dir__ of Foo object at 0x7f8d71a8c580>, '__doc__': None, ...SNIPPED... '__str__': <method-wrapper '__str__' of Foo object at 0x7f8d71a8c580>, '__subclasshook__': <built-in method __subclasshook__ of type object at 0x1e84620>, 'bar': 'baz'} """
Code language: Python (python)

As we can see it properly includes the bar attribute with its value baz despite bar being included in __slots__.

If you want to exclude the built-in attributes then we can modify the code to ignore attributes starting and ending with __:

class Foo: __slots__ = ['bar'] def __init__(self, bar): self.bar = bar foo = Foo('baz') pprint.pprint({ attr: getattr(foo, attr) for attr in dir(foo) if not attr.startswith('__') and not attr.endswith('__') }) """ Output: {'bar': 'baz'} """
Code language: Python (python)

Using inspect.getmembers()

Another way to print an object’s attributes and values is to use the inspect.getmembers() function from the Python standard library. This works well but attributes included in __slots__ will be excluded!

import inspect print(inspect.getmembers(my_dog)) # Output: [('__class__', <class '__main__.Dog'>), ('__delattr__', <method-wrapper '__delattr__' of Dog object at 0x7f8d724628b0>), ('__dict__', {'name': 'Fido', 'breed': 'Labrador', 'age': 3}), ('__dir__', <built-in method __dir__ of Dog object at 0x7f8d724628b0>), ('__doc__', None), ('__eq__', <method-wrapper '__eq__' of Dog object at 0x7f8d724628b0>), ('__format__', <built-in method __format__ of Dog object at 0x7f8d724628b0>), ('__ge__', <method-wrapper '__ge__' of Dog object at 0x7f8d724628b0>), ('__getattribute__', <method-wrapper '__getattribute__' of Dog object at 0x7f8d724628b0>), ('__gt__', <method-wrapper '__gt__' of Dog object at 0x7f8d724628b0>), ('__hash__', <method-wrapper '__hash__' of Dog object at 0x7f8d724628b0>), ('__init__', <bound method Dog.__init__ of <__main__.Dog object at 0x7f8d724628b0>>), ('__init_subclass__', <built-in method __init_subclass__ of type object at 0x1e733b0>), ('__le__', <method-wrapper '__le__' of Dog object at 0x7f8d724628b0>), ('__lt__', <method-wrapper '__lt__' of Dog object at 0x7f8d724628b0>), ('__module__', '__main__'), ('__ne__', <method-wrapper '__ne__' of Dog object at 0x7f8d724628b0>), ('__new__', <built-in method __new__ of type object at 0x9075a0>), ('__reduce__', <built-in method __reduce__ of Dog object at 0x7f8d724628b0>), ('__reduce_ex__', <built-in method __reduce_ex__ of Dog object at 0x7f8d724628b0>), ('__repr__', <method-wrapper '__repr__' of Dog object at 0x7f8d724628b0>), ('__setattr__', <method-wrapper '__setattr__' of Dog object at 0x7f8d724628b0>), ('__sizeof__', <built-in method __sizeof__ of Dog object at 0x7f8d724628b0>), ('__str__', <method-wrapper '__str__' of Dog object at 0x7f8d724628b0>), ('__subclasshook__', <built-in method __subclasshook__ of type object at 0x1e733b0>), ('__weakref__', None), ('age', 3), ('breed', 'Labrador'), ('name', 'Fido')]
Code language: Python (python)

To make this more readable we can use the pprint library from the standard library:

import pprint import inspect pprint.pprint(dict(inspect.getmembers(my_dog)) """ Output: {'__class__': <class '__main__.Dog'>, '__delattr__': <method-wrapper '__delattr__' of Dog object at 0x7f8d724628b0>, '__dict__': {'age': 3, 'breed': 'Labrador', 'name': 'Fido'}, ...SNIPPED... '__str__': <method-wrapper '__str__' of Dog object at 0x7f8d724628b0>, '__subclasshook__': <built-in method __subclasshook__ of type object at 0x1e733b0>, '__weakref__': None, 'age': 3, 'breed': 'Labrador', 'name': 'Fido'} """
Code language: Python (python)

Using vars() and __dict__

If you are only wanting to get all of an object’s non-inherited attributes and values, you can instead use vars() or __dict__. But again, these will not return the attributes defined in __slots__.

If you want to pretty print the output with indentation then you can use pprint.pprint() from the Python standard library.

Here’s an example of how to do it:

import pprint class Dog: def __init__(self, name, age, breed): self.name = name self.age = age self.breed = breed def bark(self): print("Woof!") # create a new dog instance dog1 = Dog("Fido", 3, "Labrador") print(vars(dog1)) # output: {'age': 3, 'breed': 'Labrador', 'name': 'Fido'} print(dog1.__dict__) # output: {'age': 3, 'breed': 'Labrador', 'name': 'Fido'} pprint.pprint(dog1.__dict__) # output: {'age': 3, 'breed': 'Labrador', 'name': 'Fido'}
Code language: Python (python)

In the example above, it looks like all 3 methods do the same thing but there are actually some subtle, yet important, differences.

pprint.pprint() will print the output to stdout while vars and __dict__ on the other hand will return a string.

But with pprint if you want a string instead of printing to the console, you can use the lesser-known pprint.pformat function instead.

For example:

output = pprint.pformat(dog1.__dict__) print(result) # {'age': 3, 'breed': 'Labrador', 'name': 'Fido'}
Code language: Python (python)

You can also customize the output of pprint (and pformat) by using the indent and width parameters. For example:

pprint.pprint(dog1.__dict__, indent=4)
Code language: Python (python)

This will add four spaces of indentation to each level of the instance’s attributes.

Also, while the output in this example is identical, pprint will shine when the object has more attributes because the indentation can make it much more readable.

Let’s show an example with a class that has a dozen different attributes:

import pprint class Person: def __init__(self, name, age, gender, occupation, height, weight, education, address, phone, email, hobbies, interests): self.name = name self.age = age self.gender = gender self.occupation = occupation self.height = height self.weight = weight self.education = education self.address = address self.phone = phone self.email = email self.hobbies = hobbies self.interests = interests person1 = Person("John Smith", 35, "male", "software developer", 180, 75, "Bachelor's degree", "123 Main Street", "555-123-4567", "[email protected]", ["reading", "running"], ["tech", "music"]) print(vars(person1)) # Output: {'name': 'John Smith', 'age': 35, 'gender': 'male', 'occupation': 'software developer', 'height': 180, 'weight': 75, 'education': "Bachelor's degree", 'address': '123 Main Street', 'phone': '555-123-4567', 'email': '[email protected]', 'hobbies': ['reading', 'running'], 'interests': ['tech', 'music']} pprint.pprint(vars(person1)) # Output: # {'address': '123 Main Street', # 'age': 35, # 'education': "Bachelor's degree", # 'email': '[email protected]', # 'gender': 'male', # 'height': 180, # 'hobbies': ['reading', 'running'], # 'interests': ['tech', 'music'], # 'name': 'John Smith', # 'occupation': 'software developer', # 'phone': '555-123-4567', # 'weight': 75}
Code language: Python (python)

The vars() function returns a dictionary containing the attributes of the person1 instance, while the pprint() function pretty-prints the dictionary returned by vars(), making it more readable by formatting it with indentation and line breaks.

Using __repr__

You can also define a __repr__ method in the Dog class to specify how the instance should be represented as a string. Here’s an example:

class Dog: def __init__(self, name, age, breed): self.name = name self.age = age self.breed = breed def __repr__(self): return f"Dog(name='{self.name}', age={self.age}, breed='{self.breed}')" # create a new dog instance dog1 = Dog("Fido", 3, "Labrador") # print the dog instance print(dog1) # prints "Dog(name='Fido', age=3, breed='Labrador')"
Code language: Python (python)

This will output the instance as a string in the specified format whenever you print it.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *