Home > database >  How __init__ works for inheritance
How __init__ works for inheritance

Time:11-20

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()

see more

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.

  • Related