Podcast Multi-Inheritance and MRO Sequential Learning Notes

Posted by ugh82 on Sat, 25 Jan 2020 03:08:00 +0100

1. Call methods of parent class separately

# coding=utf-8

print("******Use class names for multiple inheritance.__init__ The state of occurrence******")
class Parent(object):
    def __init__(self, name):
        print('parent Of init Start Called')
        self.name = name
        print('parent Of init End Called')

class Son1(Parent):
    def __init__(self, name, age):
        print('Son1 Of init Start Called')
        self.age = age
        Parent.__init__(self, name)
        print('Son1 Of init End Called')

class Son2(Parent):
    def __init__(self, name, gender):
        print('Son2 Of init Start Called')
        self.gender = gender
        Parent.__init__(self, name)
        print('Son2 Of init End Called')

class Grandson(Son1, Son2):
    def __init__(self, name, age, gender):
        print('Grandson Of init Start Called')
        Son1.__init__(self, name, age)  # Initialization method of parent class invoked separately
        Son2.__init__(self, name, gender)
        print('Grandson Of init End Called')

gs = Grandson('grandson', 12, 'male')
print('Full name:', gs.name)
print('Age:', gs.age)
print('Gender:', gs.gender)

print("******Use class names for multiple inheritance.__init__ The state of occurrence******\n\n")

Run result:

******Multiple Inheritance Using Class Name. u init_u Occurred State****
Grandson's init begins to be called
 Son1 init started to be called
 parent's init begins to be called
 parent's init end was called
 Son1 init end called
 Son2 init started to be called
 parent's init begins to be called
 parent's init end was called
 Son2 init end called
 Grandson's init end was called
 Name: grandson
 Age: 12
 Gender: Male
 ******Multiple Inheritance Using Class Name. u init_u Occurred State****

2. super calls overridden methods with parent classes in multiple inheritance

print("******Multiple Inheritance Use super().__init__ The state of occurrence******")
class Parent(object):
    def __init__(self, name, *args, **kwargs):  # To avoid multiple inheritance errors, use variable-length parameters and accept parameters
        print('parent Of init Start Called')
        self.name = name
        print('parent Of init End Called')

class Son1(Parent):
    def __init__(self, name, age, *args, **kwargs):  # To avoid multiple inheritance errors, use variable-length parameters and accept parameters
        print('Son1 Of init Start Called')
        self.age = age
        super().__init__(name, *args, **kwargs)  # To avoid multiple inheritance errors, use variable-length parameters and accept parameters
        print('Son1 Of init End Called')

class Son2(Parent):
    def __init__(self, name, gender, *args, **kwargs):  # To avoid multiple inheritance errors, use variable-length parameters and accept parameters
        print('Son2 Of init Start Called')
        self.gender = gender
        super().__init__(name, *args, **kwargs)  # To avoid multiple inheritance errors, use variable-length parameters and accept parameters
        print('Son2 Of init End Called')

class Grandson(Son1, Son2):
    def __init__(self, name, age, gender):
        print('Grandson Of init Start Called')
        # When multiple inheritance occurs, each parent class must be written all once instead of using the class name. u init_u method
        # Sup executes all parent class methods in one sentence, which is one reason why inheritance requires all arguments
        # super(Grandson, self).__init__(name, age, gender)
        super().__init__(name, age, gender)
        print('Grandson Of init End Called')

print(Grandson.__mro__)

gs = Grandson('grandson', 12, 'male')
print('Full name:', gs.name)
print('Age:', gs.age)
print('Gender:', gs.gender)
print("******Multiple Inheritance Use super().__init__ The state of occurrence******\n\n")

Run result:

****** Multi-inheritance state occurring with super(). u init_ ****
(<class '__main__.Grandson'>, <class '__main__.Son1'>, <class '__main__.Son2'>, <class '__main__.Parent'>, <class 'object'>)
Grandson's init begins to be called
 Son1 init started to be called
 Son2 init started to be called
 parent's init begins to be called
 parent's init end was called
 Son2 init end called
 Son1 init end called
 Grandson's init end was called
 Name: grandson
 Age: 12
 Gender: Male
 ****** Multi-inheritance state occurring with super(). u init_ ****

Be careful:

  1. The results of the above two codes are different
  2. If the parent is inherited from both subclasses, parent is executed twice when called through the parent name in the subclass
  3. If the parent is inherited from both subclasses, parent is executed once when called through super in the subclass

3. super in single inheritance

print("******Single Inheritance Use super().__init__ The state of occurrence******")
class Parent(object):
    def __init__(self, name):
        print('parent Of init Start Called')
        self.name = name
        print('parent Of init End Called')

class Son1(Parent):
    def __init__(self, name, age):
        print('Son1 Of init Start Called')
        self.age = age
        super().__init__(name)  # Single inheritance cannot provide all parameters
        print('Son1 Of init End Called')

class Grandson(Son1):
    def __init__(self, name, age, gender):
        print('Grandson Of init Start Called')
        super().__init__(name, age)  # Single inheritance cannot provide all parameters
        print('Grandson Of init End Called')

gs = Grandson('grandson', 12, 'male')
print('Full name:', gs.name)
print('Age:', gs.age)
#print('gender:', gs.gender)
print("******Single Inheritance Use super().__init__ The state of occurrence******\n\n")

summary

  1. Super(). u init_ Usage on single inheritance is almost the same as class name. u init_u Usage on single inheritance
  2. However, there is a difference in multiple inheritance. The super method guarantees that each parent class's method will execute only once, while the method using the class name will result in the method being executed multiple times, depending on the previous output
  3. When multiple inheritance occurs, the super method should be used to pass parameters to the parent class because of the super algorithm in python. All parameters must be passed, otherwise errors will occur
  4. When single inheritance is used, the super method cannot be passed all, only the parameters required by the parent method can be passed, otherwise errors will be reported
  5. When multiple inheritance occurs, instead of using the class name. u init_u method, each parent class is written once, while using the super method, all the parent class's methods are executed in a single sentence, which is one reason why multiple inheritance requires all the passed-on

super() allows you to skip some of the steps that will be executed.

Calf Knife (below are interview questions)

What will the output of the following code be? Say your answer and explain.

class Parent(object):
    x = 1

class Child1(Parent):
    pass

class Child2(Parent):
    pass

print(Parent.x, Child1.x, Child2.x)
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)

Answer, the output of the above code is:

1 1 1
1 2 1
3 2 3

What confuses or surprises you is that the output on the last line is 323 instead of 321.Why does changing the value of Parent.x change the value of Child2.x, but at the same time the value of Child1.x does not change?

The key to this answer is that in Python, class variables are treated internally as dictionaries.If the name of a variable is not found in the dictionary of the current class, the ancestor class (such as the parent class) is searched until the referenced variable name is found (an AttributeError exception is raised if the referenced variable name is neither found in its own class nor in the ancestor class).

Therefore, setting x = 1 in the parent class causes the class variable x to have a value of 1 in the reference class and any of its subclasses.This is because the output of the first print statement is 111.

Subsequently, if any of its subclasses overrides the value (for example, we execute the statement Child1.x = 2), then the value is only changed in the subclass.This is why the output of the second print statement is 121.

Finally, if the value is changed in the parent class (for example, if we execute the statement Parent.x = 3), the change will affect the value in any subclass that does not override the value (in this case, the affected subclass is Child2).This is why the third print output is 323.

655 original articles were published. 206 were approved. 89,000 visits+
His message board follow

Topics: Python