In single inheritance, the functions implemented by super() and __init__() are similar
class Base(object): def __init__(self): print 'Base create' class childA(Base): def __init__(self): print 'creat A ', Base.__init__(self) class childB(Base): def __init__(self): print 'creat B ', super(childB, self).__init__() base = Base() a = childA() b = childB()
Output result:
Base create creat A Base create creat B Base create
The difference is that you don’t need to explicitly reference the base class when using super() inheritance.
super() can only be used in new-style classes
Change the base class to an old-style class, that is, do not inherit any base class
class Base(): def __init__(self): print 'Base create'
When executed, an error will be reported when initializing b:
super(childB, self).__init__() TypeError: must be type, not classobj
super is not the parent class, but the next class in the inheritance sequence
In the case of multiple inheritance, the inheritance order is involved. super() is equivalent to returning the next class in the inheritance order, not the parent class, similar to this function:
def super(class_name, self): mro = self.__class__.mro() return mro[mro.index(class_name) + 1]
mro() is used to obtain the inheritance order of classes.
For example:
class Base(object): def __init__(self): print 'Base create' class childA(Base): def __init__(self): print 'enter A ' # Base.__init__(self) super(childA, self).__init__() print 'leave A' class childB(Base): def __init__(self): print 'enter B ' # Base.__init__(self) super(childB, self).__init__() print 'leave B' class childC(childA, childB): pass c = childC() print c.__class__.__mro__
The output results are as follows:
enter A enter B Base create leave B leave A (<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)
supder is not related to the parent class, so the execution order is A —> B—>—>Base
The execution process is equivalent to: when initializing childC(), it will first call super(childA, self).__init__() in the constructor of childA. super(childA, self) returns the one after childA in the inheritance order of the current class. Class childB; then execute childB().__init()__, and continue in this order.
In multiple inheritance, if you replace super(childA, self).__init__() in childA() with Base.__init__(self), during execution, after inheriting childA, it will jump directly to the Base class, which is omitted Passed childB:
enter A Base create leave A (<class '__main__.childC'>, <class '__main__.childA'>, <class '__main__.childB'>, <class '__main__.Base'>, <type 'object'>)
As can be seen from the super() method, the first parameter of super() can be the name of any class in the inheritance chain,
If it is itself, it will inherit the next class in turn;
If it is the previous class in the inheritance chain, it will recurse infinitely;
If it is a class later in the inheritance chain, the class between the inheritance chain summary itself and the incoming class will be ignored;
For example, if you change super in childA() to: super(childC, self).init(), the program will recurse infinitely.
For example:
File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__ super(childC, self).__init__() RuntimeError: maximum recursion depth exceeded while calling a Python object
super() can avoid repeated calls
If childA is based on Base, childB inherits childA and Base, and if childB needs to call Base's __init__() method, __init__() will be executed twice:
class Base(object): def __init__(self): print 'Base create' class childA(Base): def __init__(self): print 'enter A ' Base.__init__(self) print 'leave A' class childB(childA, Base): def __init__(self): childA.__init__(self) Base.__init__(self) b = childB()
Base’s __init__() method is executed twice
enter A Base create leave A Base create
Use super() to avoid repeated calls
class Base(object): def __init__(self): print 'Base create' class childA(Base): def __init__(self): print 'enter A ' super(childA, self).__init__() print 'leave A' class childB(childA, Base): def __init__(self): super(childB, self).__init__() b = childB() print b.__class__.mro() enter A Base create leave A [<class '__main__.childB'>, <class '__main__.childA'>, <class '__main__.Base'>, <type 'object'>]
The above is the difference between super() and __init__() in python classes that the editor introduces to you. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. I would also like to thank you all for your support of the Script House website!