The definition of super in official documents is not so much, it basically means that returning a proxy object allows you to invoke some inherited methods, and the mechanism of lookup follows the MRO rules, the most common of which is shown in the following example:
Class C (B): def method (self, arg): super (C, Self). Method (ARG)
Subclass C Overrides a method of the same name in the parent class B, calling the parent class's method with the same name in the overridden implementation through a super-instantiated proxy object.
The initial method signature of the Super class is as follows:
def __init__ (self, type1, type2=none): # Known special case of super.__init__ "" " super (Type, obj), bound sup Er object; Requires Isinstance (obj, type) super (type), unbound Super Object super (type, type2), bound Super Object ; Requires Issubclass (type2, type) Typical use-call a cooperative superclass method:
Accept one or two arguments except for self, as in the comment Declaration, the super instance of the binding is returned when two arguments are accepted, and when the second argument is omitted, the unbound super object is returned.
In general, when you call an inherited class method or static method, you do not need to bind a specific instance, this time using super (type, type2). Some_method can achieve the goal, of course super (type, obj) in this case can also be used, The GetAttribute method of a Super object with a custom implementation can also be handled. However, the latter is generally used to invoke instance methods, so that when a method is found, it can pass in the corresponding instance, thus obtaining an instance method of the binding:
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
<__main__.b object="" at="" 0x02da3570="">
>>>> 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 the Super object is initialized, the second parameter passed is actually a bound object, and the first parameter perception can be roughly understood as the starting point for the tag lookup, as in the example above: Super (b, b). Test will be in b.__mro__. Find method test in the class except for B itself, because the method is non-data descriptor, in the Super object's custom getattribute actually translates into a.__dict[' test '].__get__ (b, b).
Super is used in many places, except that the program does not have to hardcode the specified type to make the code more dynamic, there are other specific things to do, such as the use of super in the Meta class to find baseclass inside the new build custom type template To prevent infinite loops and so on when customizing GetAttribute.
About Super recommends that readers understand it with Python descriptors, because super implements the descriptor protocol and is a non-data descriptor that can help you better understand how super works and how you work.
At the same time, there are 4 points worthy of attention:
1. The functions of super () and __init__ () are similar when single inheritance is implemented.
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 use super () inheritance without explicitly referencing the base class.
2, super () can only be used in the new class
Change base class to Legacy class, that is, do not inherit any base class
Class Base (): def __init__ (self): print ' base create '
When executing, an error occurs when initializing B:
Super (CHILDB, self). __init__ () Typeerror:must is type, not classobj
3, super is not the parent class, but the next class of inheritance order
In multiple inheritance, the inheritance order is involved, and super () is equivalent to the next class that returns the inheritance order, not the parent class, similar to the functionality:
Def super (class_name, self): MRO = SELF.__CLASS__.MRO () return Mro[mro.index (class_name) + 1]
MRO () is used to obtain the class inheritance order.
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 results are as follows:
Enter a enter B Base createleave bleave A (
,
,,,
)
The supder is not associated with the parent class, so the order of execution is a-> b->->base
The execution process is equivalent to: when initializing CHILDC (), the first call to the super (Childa, self) in Childa's construction method. __init__ (), super (Childa, self) Returns a class childb after Childa in the inheritance order of the current class, and then executes Childb (). __init () __, in this order.
In multiple inheritance, if the super (Childa, self) in Childa () is changed to base.__init__ (self), when executed, the inheritance Childa will jump directly into the base class and skip the CHILDB:
Enter a Base createleave a (,,,
,
)
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 succession;
If it is in the inheritance chain before the class will be infinite recursion down;
If the following class is in the inheritance chain, the class between the inheritance chain summary itself and the passed-in class is ignored;
For example, change the super in Childa () to: Super (CHILDC, self). __init__ (), the program will be recursive indefinitely.
Such as:
File "c:/users/administrator/desktop/crawler/learn.py", line ten, in __init__ super (CHILDC, self). __init__ () file "C:/us ers/administrator/desktop/crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" c:/users/ administrator/desktop/crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" c:/users/ administrator/desktop/crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" c:/users/ administrator/desktop/crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" c:/users/ administrator/desktop/crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" c:/users/ administrator/desktop/crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" c:/users/ administrator/desktop/crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" c:/users/ administrator/desktop/crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" C:/users/administrator/desktop/crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" C:/users/administrator /desktop/crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" c:/users/administrator/desktop/ crawler/learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () File" c:/users/administrator/desktop/crawler/ learn.py ", line ten, in __init__ super (CHILDC, self). __init__ () runtimeerror:maximum recursion depth exceeded while Callin G A Python Object
4, super () can avoid repeated calls
If Childa base base, Childb inherits Childa and base, if CHILDB needs to call Base's __init__ () method, it will cause __init__ () to be executed two times:
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 __init__ () method was executed two times enter A base Createleave Abase Create uses super () to avoid repeating calls to 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[,,,
]