super() in Python 2026: Method Resolution & Modern Inheritance Patterns
The built-in super() function is used to call a method from a parent (or sibling) class in the method resolution order (MRO). In 2026 it remains the standard, safe, and most Pythonic way to handle inheritance, especially in complex multiple inheritance hierarchies, cooperative multiple inheritance, and when building extensible frameworks or libraries.
With Python 3.12–3.14+ improving MRO handling, better type hinting for super calls, and free-threading compatibility for concurrent method resolution, super() is more reliable and performant than ever. This March 24, 2026 update explains how super() works today, real-world patterns (cooperative inheritance, alternative constructors, mixin classes), common pitfalls, and best practices for clean, maintainable inheritance in modern Python.
TL;DR — Key Takeaways 2026
super()→ returns a proxy object that delegates method calls to parent classes following MRO- Modern usage:
super().method()orsuper(ClassName, self).method() - 2026 best practice: Always use
super()without arguments inside methods for cooperative inheritance - Main use cases: calling parent __init__, method overriding, mixin classes, cooperative multiple inheritance
- Type-safe pattern: Works seamlessly with type hints and Self in 2026
- Performance: Minimal overhead — MRO is precomputed
1. Basic Usage — Calling Parent Methods
class Animal:
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self):
parent_sound = super().speak()
return f"{parent_sound} - Woof!"
d = Dog()
print(d.speak()) # "Some sound - Woof!"
2. Real-World Patterns in 2026
Cooperative Multiple Inheritance (Mixin Pattern)
class LoggerMixin:
def log(self, msg: str):
print(f"[LOG] {msg}")
class DatabaseMixin:
def connect(self):
print("Connecting to database...")
class UserService(LoggerMixin, DatabaseMixin):
def save_user(self, user):
super().log(f"Saving user: {user}")
super().connect()
print("User saved")
service = UserService()
service.save_user("Alice")
Proper __init__ Chaining
class Base:
def __init__(self, name: str):
self.name = name
class Advanced(Base):
def __init__(self, name: str, version: str):
super().__init__(name) # calls Base.__init__
self.version = version
obj = Advanced("Python", "2026")
print(obj.name, obj.version) # Python 2026
Dynamic Method Resolution
class A:
def method(self):
print("A")
class B(A):
def method(self):
print("B")
super().method()
class C(A):
def method(self):
print("C")
super().method()
class D(B, C):
def method(self):
print("D")
super().method()
d = D()
d.method() # D → B → C → A (follows MRO)
3. super() vs Alternatives – Comparison 2026
| Approach | Safety | Cooperative Inheritance? | Best For |
|---|---|---|---|
| super().method() | High | Yes | Modern, cooperative inheritance |
| Parent.method(self) | Medium | No | Simple single inheritance |
| super(Class, self).method() | Medium | Yes | Legacy or explicit control |
4. Best Practices & Performance in 2026
- Use bare super() inside methods — no arguments needed in Python 3
- Type hints 2026:
from typing import Self class Base: def __init__(self): ... class Child(Base): def __init__(self): super().__init__() - Performance: super() has minimal overhead — MRO is precomputed
- Free-threading (3.14+): Safe when used correctly in inheritance chains
- Avoid: Calling super() in __new__ or outside methods without explicit class/self
super() Follows the MRO
super() does not simply mean "my parent class". It returns a proxy that finds the next class in the method resolution order (MRO) of the actual object. With single inheritance that is the parent, but with multiple inheritance it may be a sibling class. This is what makes cooperative mixins work, provided every class in the chain calls super() as well.
Worked Example: Reading the MRO
This example shows the order in which methods run.
class Base:
def setup(self):
print("Base")
class Logging(Base):
def setup(self):
print("Logging")
super().setup()
class Caching(Base):
def setup(self):
print("Caching")
super().setup()
class Service(Logging, Caching):
pass
Service().setup() # Logging, Caching, Base
print([c.__name__ for c in Service.__mro__])
# ['Service', 'Logging', 'Caching', 'Base', 'object']
Logging's super() calls Caching, not Base, because Caching is next in the MRO of Service. Base still runs only once.
Common Mistakes
- Calling
Parent.method(self)directly: it breaks cooperative chains - Inconsistent signatures: accept and pass on
**kwargsin cooperative__init__methods - Forgetting
super().__init__(): parent attributes are never set
Quick Summary
super()follows the MRO of the instance- Inspect it with
Class.__mro__ - Every class in the chain must cooperate
Conclusion — super() in 2026: Inheritance Foundation
super() is Python’s elegant solution for proper method resolution in inheritance hierarchies — especially powerful with multiple inheritance and mixins. In 2026, use bare super() for clean cooperative inheritance, combine it with type hints, and rely on it in frameworks, plugins, and extensible class designs. It’s safe, efficient, and one of Python’s most important tools for building maintainable object-oriented code.
Next steps:
- Use super() in your next class that inherits from another