Below code shows two classes Employee and Developer. A parent and a child.
class Employee(object): def __init__(self, first, last): self.first = first self.last = last print 'Employee: {0}, {1}'.format(first, last) def hike_category(self): hike = 0 if self.grade == 'A': hike = (0.1*self.pay) + self.pay #percent elif self.grade == 'B': hike = (0.15*self.pay) + self.pay #percent elif self.grade == 'C': hike = (0.20*self.pay) + self.pay #percent return '{0},{1} gets {2}'.format(self.first, self.last, hike) class Developer(Employee): def __init__(self, fname, lname, grade, pay): super(Developer, self).__init__(fname, lname) self.grade = grade self.pay = pay
Lets run the above program.
Results:
>>> d = Developer('arc', 'roy', 'C', 10000) Employee: arc, roy >>> d.hike_category() 'arc,roy gets 12000.0'
Observations and things to note
- Above programming is done in Python 2.7.
- In 2.7, the class needs to inherit from object , otherwise it wont work.
- The variable names can be different in both classes (In 2.7 only).
- super needs to have same class name as first argument.
- The class instance 'b' can access all class variables of both classes.
How it works:
In Python 2.7,super() is used to call a method from the parent class without directly writing the parent class’s name. Instead of calling
ParentClass.method(self), you write super(CurrentClass, self).method(). Python then looks at the inheritance order (called the Method Resolution Order, or MRO) and runs the method from the next class in that order.What really happens when we use super call ?
Python starts looking as to which method should it call.
There is a order in which it does this. That order is called the MRO. Method Resolution Order.
This decides, which method will be called, when we use the Child class.
In our example:
super(Developer, self).__init__(fname, lname)
When this line executes, python starts looks up the order.
- The 1st one, is the the current class itself. Developer. When you call any method inside the Developer class, it will first look right here, In this class.
- If it does not find in the chile class, next in order is the Parent class: Employee.
- If it STILL does NOT find it, next in order is : object
Can we verify this theory ?
Yes of course. Every modern class (in Python 2.7, classes inheriting the "object"), has a special method :
__mro__
If you call this , you can see a tuple of classes . The order is important here. Left to Right.
>>> Developer.__mro__
(<class '__main__.Developer'>, <class '__main__.Employee'>, <class 'object'>)
This is the order of classes that will be looked upon when a method is called.
Updates in Python 3.12+
Now a lot many things have changed since. But in the this topic, the way of things has changed a bit, for the better.
In Python 3.12+,
super() is cleaner, safer, and easier to use than in Python 2.7.class Employee: def __init__(self, first, last): self.first = first self.last = last class Developer(Employee): def __init__(self, first, last, pay): super().__init__(first, last) self.pay = pay
In Python 2.7, you HAD to write:
super(Developer, self).__init__(first, last)
But now,
super().__init__(first, last)
Python now finds automatically which classes are involved.
Python uses C3 linearization to compute this order.
That means method lookup is:
-
Current class
-
Parent class
-
Parent of parent
-
object
But it becomes very important in multiple inheritance.
Here is a new example (Python 3.12+):
class A: def say(self): print("A") class B(A): def say(self): super().say() print("B") class C(A): def say(self): super().say() print("C") class D(B, C): def say(self): super().say() print("D") d = D() d.say()
Output:
A C B D
Why this happens?
Python follows the Method Resolution Order (MRO). If you check:
>>> D.__mro__ (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
Each
super() call moves to the next class in this order.
This is why Python prints: A → C → B → D.
No comments:
Post a Comment