Why do Python classes inherit object?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
In the realm of Python programming, understanding why classes inherit from object is crucial for building efficient and modern Python applications. This article delves into the rationale and technical details of this inheritance, focusing on the distinctions between classic and new-style classes in Python, the advantages of inheriting from object, and some key points to consider when designing your Python classes.
A Historical Overview: Classic vs. New-Style Classes
To grasp why Python classes inherit object, it is helpful to understand the evolution of classes in Python.
Classic Classes
Before Python 2.2, all classes were considered "classic" or "old-style." These classes did not inherit from any base class implicitly or explicitly, and they represented objects using a simple mechanism similar to C structs. Classic classes had limitations, including:
- Lack of a unified object model.
- Some advanced features such as descriptors, properties, and super calls were not supported.
Introduction of New-Style Classes
With the introduction of Python 2.2, a new model was presented in the form of "new-style classes." A key feature of these classes is that they explicitly inherit from the object class or any subclass of it. This change aimed to unify types and classes, offering:
- A consistent object model by having a common ancestor in the form of
object. - Enhanced capabilities such as descriptors, magic methods, and better support for multiple inheritance.
Key Features of New-Style Classes
The adoption of object as a base class brought several benefits:
- Unified Type System: In new-style classes, everything derives from
object, making functions such asisinstance()andissubclass()more reliable and efficient. - Rich API: New-style classes offer a variety of methods and attributes absent in classic classes, such as
__slots__,__getattribute__, and__mro__. - Descriptor Protocol: This includes properties and static/class methods, facilitating more Pythonic code designs.
- Cooperative Multiple Inheritance: The C3 method resolution order (MRO) allows for a more predictable and well-structured hierarchy.
Technical Explanation: Why Inherit from object?
Any class defined in Python 3, other than built-in classes, is implicitly a new-style class because Python 3 does not support classic classes. However, in Python 2.x, a programmer must explicitly inherit from object to leverage the new-style class features. Here is why inheriting from object is advised:
Example: Utilizing super()
The super() function is a potent tool enabled by new-style classes that allows a programmer to call methods up the class hierarchy without hardcoding the parent class name:
Output:
Without inheriting from object, super() would be ineffective or could result in errors.
Method Resolution Order (MRO)
The MRO defines the order in which base classes are searched when executing a method. In new-style classes, MRO uses the C3 algorithm, ensuring a more deterministic order:
Output:
Summary Table
| Feature | Classic Classes | New-Style Classes |
| Base class | None | object |
| Descriptor protocol | Not supported | Supported |
| Method Resolution Order | Depth-first, left-to-right | C3 linearization |
super() functionality | Limited | Full support |
| Common base type support | None | Unified type system with object |
Conclusion
In summary, inheriting from object when defining Python classes is essential for tapping into the full potential of Python's modern object-oriented capabilities. This practice encapsulates not only enhanced functionalities, like cooperative multiple inheritance and reliable property creation, but also aligns with Python's philosophy for uniformity and predictability.
Adopting new-style classes by inheriting from object is not just advantageous but necessary in the context of Python 3, paving the way toward a robust and clean application design.

