I cant have 2 init methods in one class because of function overloading. However, why is it possible that when initializing a subclass, im able to define a new __init__
method, and use the super().__init__
method or the parentclass init method within the subclass __init__
method. i'm just a little confused by the concept of 2 __init__
methods functioning at the same time
class Employee:
emps = 0
def __init__(self,name,age,pay):
self.name = name
self.age = age
self.pay = pay
class Developer(Employee):
def __init__(self,name,age,pay,level):
Employee.__init__(self,name,age,pay)
self.level = level
CodePudding user response:
The “init” is a reserved method in python classes. It is known as a constructor in Object-Oriented terminology. This method when called, allows the class to initialize the attributes of the class.
#base class
class State():
def __init__(self):
print("In the state class")
self.state1= "Main State"
#derived class
class HappyState():
def __init__(self):
print("In the happystate class")
self.state2= "Happy State"
super().__init__()
a=HappyState()
print(a.state1)
print(a.state2)
The super() function allows us to avoid using the base class name explicitly. In Python, the super() function is dynamically called as unlike other languages, as it is a dynamic language. The super() function returns an object that represents the parent class. In a subclass, a parent class can be referred to using the super() function. It returns a temporary object of the superclass and this allows access to all of its methods to its child class. While using the super() keyword, we need not specify the parent class name to access its methods.
#base class1
class State():
def __init__(self):
print("In the State class")
self.state1= "Main State"
#base class2
class Event():
def __init__(self):
print("In the Event class")
self.event= "Main Event"
#derived class
class HappyState(State,Event):
def __init__(self):
print("In the happystate class")
super().__init__() #Only calls Base Class 1
a=HappyState()
CodePudding user response:
The super()
function is used to give access to methods and properties of a parent or sibling class
check out: https://www.geeksforgeeks.org/python-super/
CodePudding user response:
I cant have 2 init methods in one class because of function overloading.
Partially true. You can't have 2 __init__
methods in the same class because the language lacks function overloading. (Libraries can partially restore a limited form of function overloading; see functools.singledispatchmethod
for an example.)
i'm just a little confused by the concept of 2 init methods functioning at the same time
But you aren't trying to overload __init__
. You are overriding __init__
, providing a different definition for Developer
than the definition it inherits from Employer
. (In fact, Employer
is overriding __init__
as well, using its own definition in place of the one it inherits from object
.) Each class has only one definition.
In your definition of Developer.__init__
, you are simply making an explicit call to the inherited method to do the initialization common to all instances of Employee
, before doing the Developer
-specific initialization on the same object.
Using super
, you are using a form of dynamic lookup to let the method resolution order for instance of Developer
decide what the "next" version of __init__
available to Developer
to call. For single inheritance, the benefit is little more than avoiding the need to hard-code a reference to Employee
. But for multiple inheritance, super
is crucial to ensuring that all inherited methods (both the ones you know about and the ones you may not) get called, and more importantly, are called in the right order.
A full discussion of how to properly use super
is beyond the scope of this question, I think, but I'll show your two classes rewritten to make the best use of super
, and refer you to Python's super()
considered super! for more information.
# Main rules:
# 1. *All* classes use super().__init__, even if you are only inheriting
# from object, because you don't know who will use you as a base class.
# 2. __init__ should use keyword arguments, and be prepared to accept any
# keyword arguments.
# 3. All keyword arguments that don't get assigned to your own parameters
# are passed on to an inherited __init__() to process.
class Employee:
emps = 0
def __init__(self, *, name, age, pay, **kwargs):
super().__init__(**kwargs)
self.name = name
self.age = age
self.pay = pay
class Developer(Employee):
def __init__(self, *, level, **kwargs):
super().__init__(**kwargs)
self.level = level
d1 = Developer(name="Alice", age=30, pay=85000, level=1)
To whet your appetite for the linked article, consider
class A:
def __init__(self, *, x, **kwargs):
super().__init__(**kwargs)
self.x = x
class B:
def __init__(self, *, y, **kwargs):
super().__init__(**kwargs)
self.y = y
class C1(A, B):
pass
class C2(B, A):
pass
c1 = C1(x=1, y=2)
c2 = C2(x=4, y=3)
assert c1.x == 1 and c1.y == 2
assert c2.x == 4 and c2.y == 3
The assertions all pass, and both A.__init__
and B.__init__
are called as intended when c1
and c2
are created.