inheritance in python 2.7.x
Categories:
Mastering Inheritance in Python 2.7.x

Explore the fundamentals of inheritance in Python 2.7.x, including classic vs. new-style classes, method resolution order (MRO), and the use of super()
.
Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a class (child or subclass) to inherit attributes and methods from another class (parent or superclass). This promotes code reusability and establishes a natural 'is-a' relationship between classes. While Python 3 has streamlined many aspects of inheritance, Python 2.7.x presents some nuances, particularly with 'classic' vs. 'new-style' classes and the super()
function. Understanding these distinctions is crucial for writing robust and maintainable Python 2.7.x code.
Classic vs. New-Style Classes
In Python 2.7.x, there are two types of classes: classic classes and new-style classes. The distinction is important because it affects how inheritance, especially Method Resolution Order (MRO), behaves. New-style classes are the default in Python 3 and are generally preferred in Python 2.7.x as well, as they provide a more consistent and powerful object model.
A class becomes a new-style class by inheriting from object
(either directly or indirectly). If a class does not explicitly inherit from object
or another new-style class, it is considered a classic class. New-style classes introduce features like __slots__
, descriptors, and a more predictable MRO based on the C3 linearization algorithm.
class ClassicClass:
def __init__(self):
print "Classic class initialized"
class NewStyleClass(object):
def __init__(self):
print "New-style class initialized"
# Example usage
classic_obj = ClassicClass()
new_style_obj = NewStyleClass()
Defining classic and new-style classes in Python 2.7.x
object
in Python 2.7.x to ensure your classes are new-style. This provides access to modern Python features and a more predictable inheritance model, aligning your code closer to Python 3 behavior.Method Resolution Order (MRO)
MRO is the order in which Python looks for a method in a hierarchy of classes. When you call a method on an object, Python needs to know which class's method to execute, especially in cases of multiple inheritance. The MRO determines this search path. For new-style classes, Python 2.7.x uses the C3 linearization algorithm, which provides a consistent and deterministic order.
You can inspect the MRO of a class using the __mro__
attribute or the mro()
method. Understanding MRO is critical for debugging unexpected method calls in complex inheritance hierarchies.
class A(object):
def method(self):
print "A's method"
class B(A):
def method(self):
print "B's method"
class C(A):
def method(self):
print "C's method"
class D(B, C):
def method(self):
print "D's method"
print D.__mro__
# Expected output for new-style classes: (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
Inspecting MRO for a new-style class with multiple inheritance
classDiagram class object class A class B class C class D object <|-- A A <|-- B A <|-- C B <|-- D C <|-- D
Class hierarchy for the MRO example
Using super()
for Parent Method Calls
The super()
function is used to call a method from a parent or sibling class. In Python 2.7.x, super()
has a slightly different syntax compared to Python 3. It requires you to explicitly pass the current class and the instance as arguments: super(CurrentClass, self).method_name()
.
Using super()
is crucial for cooperative multiple inheritance, ensuring that methods in the MRO are called correctly without explicit knowledge of the full inheritance chain. It helps avoid hardcoding parent class names, making your code more flexible and maintainable.
class Parent(object):
def __init__(self, value):
self.value = value
print "Parent init with value: %s" % self.value
class Child(Parent):
def __init__(self, value, extra):
super(Child, self).__init__(value) # Call parent's __init__
self.extra = extra
print "Child init with extra: %s" % self.extra
def display(self):
print "Value: %s, Extra: %s" % (self.value, self.extra)
# Example usage
child_obj = Child(10, "hello")
child_obj.display()
Using super()
in Python 2.7.x to call a parent's __init__
method
super()
syntax in Python 2.7.x. Forgetting to pass CurrentClass
and self
will result in a TypeError
. In Python 3, super()
can be called without arguments, which is a common source of confusion when porting code.