S difference between super of and s3en__ of in class python

  • 2020-05-17 05:41:59
  • OfStack

The functions of super() and s 2en__ () are similar with single inheritance


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 results:


Base create
creat A Base create
creat B Base create

The difference is that you do not explicitly refer to 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 does not inherit from any base class


class Base():
def __init__(self):
print 'Base create'

When executed, an error is reported when initializing b:


super(childB, self).__init__()
TypeError: must be type, not classobj

super is not a parent class, but the next class in the order of inheritance

When multiple inheritance involves inheritance order, super () is equivalent to returning the next class in the inheritance order instead of the parent class, which is similar to the following function:


def super(class_name, self):
mro = self.__class__.mro()
return mro[mro.index(class_name) + 1]

mro() is used to get the inheritance order of the class.

Such as:


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 associated with the parent class, so the order of execution is A -- > B - > - > Base

This process is equivalent to: when initializing childC(), first call super(childA, self) in childA's constructor method. S 58en (). S 59en (). S 59en ().

In multiple inheritance, if you replace super(childA, self). S 66en__ () with Base. S 68en__ (self), you will jump directly into Base class after inheriting childA, but skip 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's a previous class in the inheritance chain it recurses indefinitely;

If the class is next in the inheritance chain, it will ignore the class between the inheritance chain summary itself and the incoming class.

For example, if you change super from childA() to super(childC, self).init(), the program will recurse indefinitely.

Such as:


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() avoids repeated calls

If childA base Base, childB inherits childA and Base, then if childB needs to call Base's s 107en__ () method, it will result in s 108en__ () being 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()

S 112en s 113en__ () method is executed twice


Base create
creat A Base create
creat B Base create
0

Using super() is to avoid repeated calls


Base create
creat A Base create
creat B Base create
1

Related articles: