Home  >  Article  >  Backend Development  >  Explanation on the difference between super() and __init__() in python classes

Explanation on the difference between super() and __init__() in python classes

高洛峰
高洛峰Original
2017-03-16 16:08:291345browse

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.


super() can only be used in new-style classes


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


super is not the parent class, but the inheritance sequence The next class


# 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 &#39;main.childC&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.childB&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>)

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 &#39;main.childC&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.childB&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>)

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

recurse

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 &#39;Base create&#39;
class childA(Base):
    def init(self):
        print &#39;enter A &#39;
        Base.init(self)
        print &#39;leave A&#39;
class childB(childA, Base):
    def init(self):
        childA.init(self)
        Base.init(self)
b = childB()

The init() method of Base is executed twice

enter A 
Base create
leave A
Base create


Using super() can avoid repeated calls

class Base(object):
    def init(self):
        print &#39;Base create&#39;
class childA(Base):
    def init(self):
        print &#39;enter A &#39;
        super(childA, self).init()
        print &#39;leave A&#39;
class childB(childA, Base):
    def init(self):
        super(childB, self).init()
b = childB()
print b.class.mro()
enter A 
Base create
leave A
[<class &#39;main.childB&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>]

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn