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

高洛峰
Release: 2017-03-16 16:08:29
Original
1377 people have browsed it

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()
Copy after login

Output result:

Base create
creat A  Base create
creat B  Base create
Copy after login

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'
Copy after login

When executed, an error will be reported when initializing b:

super(childB, self).init()
TypeError: must be type, not classobj
Copy after login


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]
Copy after login

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
Copy after login

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;>)
Copy after login

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;>)
Copy after login

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
Copy after login


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()
Copy after login

The init() method of Base is executed twice

enter A 
Base create
leave A
Base create
Copy after login


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;>]
Copy after login

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!

Related labels:
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template