SingleInheritanceThe 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 do not need to explicitly reference the base class when using super() inheritance.
Change the base class to an old-style class , that is, it does 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
# will involve the inheritance order during multiple inheritance. 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 the class. 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 result is 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(), super(childA, self).init(), super(childA, self) returns a class childB after childA in the inheritance order of the current class; then execute childB().init(), and the sequence continues.
In multiple inheritance, if super(childA, self).init() in childA() is replaced by Base._init_(self), during execution, After inheriting childA, it will jump directly to the Base class, skipping 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 any class in the inheritance chain name,
#if it is itself, it will inherit the next class in turn; The classes will
infinitely;
If it is a class later in the inheritance chain, the relationship between the inheritance chain summary itself and the incoming class will be ignored Class;
#For example, if super is changed in childA() to: super(childC, self).init(), the program will recurse infinitely. For example:
File "test.py", line 12, in init super(childC, self).init() File "test.py", line 12, in init super(childC, self).init() File "test.py", line 12, in init super(childC, self).init() File "test.py", line 12, in init super(childC, self).init() File "test.py", line 12, in init super(childC, self).init() File "test.py", line 12, in init super(childC, self).init() File "test.py", line 12, in init super(childC, self).init() File "test.py", line 12, in init super(childC, self).init() File "test.py", line 12, 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 , if childB needs to call the init() method of Base, it will cause init() to 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()
enter A Base create leave A Base create
Using super() can 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 detailed content of Explanation on the difference between super() and __init__() in python classes. For more information, please follow other related articles on the PHP Chinese website!