Super Arguments in Python
- Super Arguments in Python
- Super Uses Inheritance Concept
- Accurate Usage of Super Arguments in Python
- Use Super to Pass Arguments to Constructors in Python Multiple Inheritance
This article’s subject is using the Python super
arguments correctly. We will also learn about the concept of super
and inheritance, appropriate examples of code using super
arguments, and the concept of base classes.
Super Arguments in Python
In Python, super
invokes a method on another class. It is called a parent class, a base class, or a superclass when a class inherits from another class.
It is pretty straightforward to use super
because it goes directly to the parent class and calls its methods.
Arguments can be passed to super
. It takes two arguments, a class and a class instance.
Example Code:
class A:
def roo(self):
return "roo() from A"
class B(A):
def roo(self):
print("roo() from B")
return super().roo()
class C(A):
def roo(self):
print("roo() from C")
return super().roo()
class D(B, C):
def roo(self):
print("roo() from D")
return super(C, self).roo()
a = A()
b = B()
c = C()
d = D()
print(a.roo())
print(b.roo())
print(c.roo())
print(d.roo())
Output:
roo() from A
roo() from B
roo() from A
roo() from C
roo() from A
roo() from D
roo() from A
Super Uses Inheritance Concept
Inheritance might seem unfamiliar if you are unfamiliar with object-oriented programming concepts. In object-oriented programming, inheritance refers to a class’s ability to derive (or inherit) attributes and behaviors from another class without implementing them again.
The convenient way to understand these concepts is to look at a code, so let’s create some classes to describe some shapes.
Example code:
class Rectangle_Shape:
def __init__(self, len, wid):
self.length = len
self.width = wid
def area(self):
return self.length * self.width
def perimeters(self):
return 2 * self.length + 2 * self.width
class Square_Shape:
def __init__(self, len):
self.length = len
def area(self):
return self.length * self.length
def perimeters(self):
return 4 * self.length
s = Square_Shape(4)
print(s.area())
r = Rectangle_Shape(3, 5)
print(r.area())
This class has two corresponding classes: Rectangle_Shape
and Square_Shape
.
Output:
16
15
The example demonstrates two shapes that are related to one another: a square is a type of rectangle. The code does not reflect that relationship, resulting in essentially repeated code.
By using inheritance, you can reduce the amount of code you write while simultaneously reflecting the real-world relationship between rectangles and squares.
Example code:
class Rectangle_Shape:
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
def perimeters(self):
return 2 * self.length + 2 * self.width
# Making the Square_Shape class that initiates the Rectangle_Shape class
class Square_Shape(Rectangle_Shape):
def __init__(self, len):
super().__init__(len, len)
s = Square_Shape(4)
print(s.area())
In this case, super()
calls init()
of the Rectangle_Shape
class, which is then used in the Square_Shape
class without having to rewrite the code.
Output:
16
As shown in the example, Rectangle_Shape
is the parent class, and Square_Shape
is the child class.
Accurate Usage of Super Arguments in Python
The code for classes M
, N
, and O
is below.
class M:
def __init__(self):
print("M initiated successfully")
class N(M):
def __init__(self):
super().__init__()
print("N initiated successfully")
class O(N):
def __init__(self):
super(O, self).__init__()
print("O initiated successfully")
o = O()
As the code above assumes, all classes overload their direct parents init()
method. super()
does not need any attributes, so using it without arguments suffices.
Output:
M initiated successfully
N initiated successfully
O initiated successfully
Suppose we want the class M2
to jump N
’s init()
method but run M
’s init()
method instead. The init()
method should be inherited from M
, not N
, despite our class’ direct parent being N
.
Here comes class M2
. Let’s take a look at its execution.
class M:
def __init__(self):
print("M initiated successfully")
class N(M):
def __init__(self):
super().__init__()
print("N initiated successfully")
class O(N):
def __init__(self):
super(O, self).__init__()
print("O initiated successfully")
class M2(N):
def __init__(self):
super(N, self).__init__()
print("other O initiated successfully")
m2 = M2()
It can be assumed from the code above that we pass attributes to the super()
method to select the correct superclass this time. As a result of running m2 = M2()
, we get the following output.
M initiated successfully
other O initiated successfully
Rather than calling the direct parent __init__()
method, we invoked M
’s init()
Python method instead.
For implicit lookups using these statements or operators such as super()[name]
, super()
is undefined.
Additionally, super()
is not limited to using inside methods aside from the zero-argument form. Using the two-argument form identifies the arguments exactly and makes the appropriate references.
In a class definition, zero arguments only work because the compiler fills in the necessary details to retrieve the class and the instance.
Use Super to Pass Arguments to Constructors in Python Multiple Inheritance
A base class should be designed for multiple inheritances if you deal with various inheritances in general.
There are times when two classes have similar parameter names. When that happens, you cannot remove key-value pairs from **kwargs
or remove them from *args
.
It is possible to define a Base
class, which, unlike an object, absorbs/ignores arguments.
Example code:
class Base(object):
def __init__(self, *args, **kwargs):
pass
class P(Base):
def __init__(self, *args, **kwargs):
print("P")
super(P, self).__init__(*args, **kwargs)
class Q(Base):
def __init__(self, *args, **kwargs):
print("Q")
super(Q, self).__init__(*args, **kwargs)
class R(P):
def __init__(self, arg, *args, **kwargs):
print("R", "arguments=", arg)
super(R, self).__init__(arg, *args, **kwargs)
class S(Q):
def __init__(self, arg, *args, **kwargs):
print("S", "arguments=", arg)
super(S, self).__init__(arg, *args, **kwargs)
class T(R, S):
def __init__(self, arg, *args, **kwargs):
print("T", "arguments=", arg)
super(T, self).__init__(arg, *args, **kwargs)
print("MRO---", [x.__name__ for x in T.__mro__])
t = T(10)
Output:
T arguments= 10
R arguments= 10
P
S arguments= 10
Q
MRO--- ['T', 'R', 'P', 'S', 'Q', 'Base', 'object']
It is important to note that Base
must be the penultimate class in the MRO
for this to work.
The Python programming language provides a wide range of features for Object-Oriented Programming. In that set, the super
function arguments play an important role, especially when used correctly.
Hopefully, this article has helped you understand better how to use the super
function arguments in Python.
My name is Abid Ullah, and I am a software engineer. I love writing articles on programming, and my favorite topics are Python, PHP, JavaScript, and Linux. I tend to provide solutions to people in programming problems through my articles. I believe that I can bring a lot to you with my skills, experience, and qualification in technical writing.
LinkedIn