The super keyword can be used when a Python subclass calls a parent class member. during initialization, pay attention to the differences between super () and _ init, next we will go into the usage of the super keyword in Python Programming: there are not many definitions about super in the official document, the general meaning is to return a proxy object so that you can call some inherited methods. The search mechanism follows the mro rules. The most common situation is shown in the following example:
class C(B): def method(self, arg): super(C, self).method(arg)
Subclass C overrides the method of the same name in parent class B, and calls the method of the same name in the parent class through the proxy object instantiated by super in the rewriting implementation.
The signature of the initial method of the super class is as follows:
def __init__(self, type1, type2=None): # known special case of super.__init__ """ super(type, obj) -> bound super object; requires isinstance(obj, type) super(type) -> unbound super object super(type, type2) -> bound super object; requires issubclass(type2, type) Typical use to call a cooperative superclass method:
Except self, one or two parameters are accepted. as stated in the annotation declaration, when two parameters are accepted, the bound super instance is returned, when the second parameter is omitted, the unbound super object is returned.
Generally, when an inherited class or static method is called, you do not need to bind a specific instance. in this case, super (type, type2) is used ). some_method can achieve the goal. of course, super (type, obj) can also be used in this case. super objects can also be processed using custom getattribute methods. However, the latter is generally used to call the instance method, so that the corresponding instance can be passed in when the method is searched to obtain the bound instance method:
class A(object): def __init__(self): pass @classmethod def klass_meth(cls): pass @staticmethod def static_meth(): pass def test(self): passclass B(A): pass>>> b = B()>>> super(B, b).test
>>>> super(B, b).klass_meth
>>>> super(B, b).static_meth
>>> super(B, B).test
>>> super(B, B).klass_meth
>>>> super(B,B).satic_meth>>> super(B,B).static_meth
When initializing the super object, the second parameter passed is actually the bound object. The first parameter sensory number can be roughly resolved as the starting point for marking the search, as shown in the preceding example: super (B, B ). test will be in B. the search method test is listed in _ mro _ apart from class B, because all methods are non-data descriptors, which will be converted to A in the custom getattribute of the super object. _ dict ['test']. _ get _ (B, B ).
Super is used in many places, except that the program does not have to specify the hardcode type to make the code more dynamic, there are other things that are required, such as using super in the meta class to find the new in baseclass to generate a custom type template, and using getattribute to prevent infinite loops.
For details about super, we recommend that you understand it with the python descriptor, because super implements the descriptor protocol, which is a non-data descriptor, this helps you better understand how super works.
Note the following four points:
1. during single inheritance, super () and _ init _ () functions 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 createcreat A Base createcreat B Base create
You do not need to explicitly reference the base class when using super () inheritance.
2. super () can only be used in new classes
Change the base class to the old class, that is, do not inherit any base class
class Base(): def __init__(self): print 'Base create'
During execution, when initializing B, an error is reported:
super(childB, self).__init__()TypeError: must be type, not classobj
3. super is not the parent class, but the next class that inherits the sequence.
In multi-inheritance, the inheritance sequence is involved. super () is equivalent to returning the next class in the inheritance sequence, rather than the parent class. This function is similar to the following:
def super(class_name, self): mro = self.__class__.mro() return mro[mro.index(class_name) + 1]
Mro () is used to obtain the inheritance sequence 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): passc = childC()print c.__class__.__mro__
The input result is as follows:
enter A enter B Base createleave Bleave A(
,
,
,
,
)
Supder is not associated with the parent class, so the execution order is A-> B-> Base
The execution process is equivalent to: when childC () is initialized, super (childA, self) in the childA constructor is called first ). _ init _ (), super (childA, self) returns a childB class after childA in the inheritance sequence of the current class, and then executes childB (). _ init () __, which is executed in this order.
In multi-inheritance, if super (childA, self) in childA () is set ). _ init _ () is replaced with Base. _ init _ (self): During execution, after inheriting childA, it will directly jump to the Base class, skipping childB:
enter A Base createleave A(
,
,
,
,
)
The super () method shows that 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 an inheritance chain, the previous classes will be infinitely recursive;
If it is the class after 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 be infinitely recursive.
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
4. super () can avoid repeated calls
If childA Base, childB inherits childA and Base, if childB needs to call the Base's _ init _ () method, it will lead to _ init __() 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 createleave ABase create uses super () yes to avoid repeated calls of 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 createleave A[
,
,
,
]