provocationofmind.com

Understanding Python's super(): Unraveling its True Purpose

Written on

Chapter 1: Unpacking super() in Python

What exactly is the super() function in Python? While many believe it simply calls a parent class method during inheritance, there's more complexity beneath the surface. Let's delve deeper into this concept and gain a comprehensive understanding of super().

Basic Inheritance

In typical inheritance scenarios, there exists one child class and one parent class. For example, when invoking super().walk() in the child class, it indeed calls the walk() method from its parent class as anticipated. This may lead to the impression that super() directly invokes the parent class method.

class Human:

def walk(self):

print("Human walks", self)

class Friend(Human):

def walk(self):

print("Friend walks", self)

super().walk()

friend = Friend()

friend.walk()

Output:

Friend walks <__main__.Friend object at 0x105142e50>

Human walks <__main__.Friend object at 0x105142e50>

Multiple Classes

Consider a scenario where Bird is a direct parent of ColorfulBird, yet it lacks a sing method. Will this lead to an error? Surprisingly, it will not. The super() function traverses the inheritance hierarchy to locate the method, demonstrating its ability to search methodically until it finds a match.

class Animal:

def sing(self):

print("Animal does cool sounds: sound1 sound2 sound3")

class Bird(Animal):

pass

class ColorfulBird(Bird):

def sing(self):

print("Colorful bird sings: Lalalalalala", self)

super().sing()

bird = ColorfulBird()

bird.sing()

Output:

Colorful bird sings: Lalalalalala <__main__.ColorfulBird object at 0x...>

Animal does cool sounds: sound1 sound2 sound3

The Diamond Problem

Let’s explore a more complex inheritance structure. We have four classes: A, B, C, and Root. Here, C inherits from both A and B, with each class containing a method invoked by super(). This raises questions about method precedence: which method gets called first? Will the Root method be executed multiple times, or will the inheritance hierarchy allow us to bypass A and B directly to the Root method?

Python utilizes a rule known as Method Resolution Order (MRO) to handle this situation. MRO flattens the diamond-shaped inheritance structure into a linear sequence, which can be viewed using the __mro__ attribute.

The MRO is computed via the C3 linearization algorithm, which systematically determines the order. Essentially, the MRO of a class C is derived by merging C with the linearization of its parent classes and their respective lists in the order they are inherited.

class Root:

def walk(self):

print("Root walk", self)

class A(Root):

def walk(self):

print("A walk", self)

super().walk()

class B(Root):

def walk(self):

print("B walk", self)

super().walk()

class C(B, A):

def walk(self):

print("C walk", self)

super().walk()

class D(C):

def walk(self):

print("D walk", self)

super().walk()

d = D()

d.walk()

Output:

D walk <__main__.D object at 0x...>

C walk <__main__.D object at 0x...>

B walk <__main__.D object at 0x...>

A walk <__main__.D object at 0x...>

Root walk <__main__.D object at 0x...>

More on __mro__

To observe the order of method calls, you can examine C.__mro__. However, it won't always yield a consistent result. The classes in the hierarchy must align correctly; if they don’t, you may encounter errors.

print(C.__mro__)

If you attempt to introduce a conflicting class, an error will arise. This occurs because Python aims to maintain the order of classes as they appear in the inheritance list while ensuring each class precedes its superclasses.

class D(A, C):

def walk(self):

print("D walk", self)

super().walk()

# TypeError: Cannot create a consistent method resolution order (MRO) for bases A, C

Super: What Are You?

The super() function can be viewed as a proxy class, allowing for method delegation.

class A:

def func(self):

print("A: ", self)

class B(A):

def func(self):

print("B: ", self)

sup = super()

print(sup)

sup.func()

b = B()

b.func()

Output:

B: <__main__.B object at 0x...>

<__main__.B object at 0x...>

A: <__main__.B object at 0x...>

Implementing a Simple Proxy

Let’s create a straightforward proxy class that allows us full control over the methods we apply to an object.

class BasicProxy:

def __init__(self, obj):

self.obj = obj

def __getattr__(self, item):

print(item)

return getattr(self.obj, item)

numbers = [1, 2, 3, 4, 5, 6, 7]

proxy = BasicProxy(numbers)

proxy.append(8)

print(proxy == numbers)

print(proxy.obj == numbers)

Output:

append

False

True

Creating a Fake Super

We can also simulate a version of super() to understand its functionality better. This imitation requires manually specifying the parent class.

class FakeSuper:

def __init__(self, cls, obj):

self.obj = obj

self.cls = cls

def __getattr__(self, item):

attr = getattr(self.cls, item)

if hasattr(type(attr), "__get__"):

attr = attr.__get__(self.obj)

print(attr)

return attr

class A:

def func(self):

print("A: ", self)

class B(A):

def func(self):

print("B: ", self)

FakeSuper(A, self).func()

b = B()

b.func()

Output:

B: <__main__.B object at 0x...>

A: <__main__.B object at 0x...>

The FakeSuper class acts as a proxy with enhanced functionality for methods, allowing for a deeper understanding of how the super() function operates.

If you found this exploration insightful and wish to join our expanding community, be sure to follow us as we embark on this knowledge journey together. Your thoughts and comments are always welcomed!

In Plain English 🚀

Thank you for being part of the In Plain English community! Before you leave, don't forget to follow us on X, LinkedIn, YouTube, Discord, and subscribe to our newsletter for more content.

A simple explanation of super() in Python - YouTube. This video clarifies the use of super() in Python inheritance.

Python super function - YouTube. An in-depth look at how the super function operates in Python.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

From Disdain to Passion: My Transformation in Chemistry

An exploration of my journey from disliking to embracing chemistry, highlighting key insights that changed my perspective.

Are We Truly Safe from the WebP Vulnerability?

Exploring the risks of the WebP vulnerability and necessary updates for software security.

Why Is There No Instagram App for iPad After All These Years?

Explore the reasons behind Instagram's absence on iPad and the implications for users.

Mastering Leadership: Why Mind Reading is a Risky Game

Exploring why relying on mind reading in leadership can lead to misunderstandings and how effective communication is key to success.

Unlocking Your Unique Edge: Why Humanity Trumps Algorithms

Discover how embracing humanity in your social media strategy can foster deeper connections and engagement.

Navigating Through the Depths of Despair: A Personal Journey

A personal account of battling depression and anxiety, highlighting the importance of self-care and reflection.

The Intriguing Science Behind the Length of a Day

Explore the fascinating science of how we measure a day on Earth and why it doesn't always equal 24 hours.

Inspiring Educators: The Impact of Great Teachers on Our Lives

Reflecting on the profound influence of inspiring teachers in shaping our lives and fostering potential.