Think of Python's super () function, pythonsuper
Python-super
Thought of by the super () function of Python
First, let's take a look.super()
Function Definition:
super([type [,object-or-type]])Return a **proxy object** that delegates method calls to a **parent or sibling** class of type.
ReturnsProxy objectThis object is responsible for calling the MethodAllocateFor the first parameterParent class or peer classComplete.
How are parent or sibling class determined?
The__mro__
The attribute determines the search order. super indicatesMRO(Method Resolution Order) in the next class,Not necessarily the parent class!
Both super () and getattr () Use__mro__
Attribute to parse the search order,__mro__
It is actually a read-only tuples.
How is the order of classes in MRO arranged?
In fact, the MRO list itself is determined by a C3 linear processing technology. For theoretical instructions, refer to here. Here we only briefly describe the principles:
In MRO, the base class always appears behind the derived class. If there are multiple base classes, the relative sequence of the base class remains unchanged.
MRO is actuallyInheritance treeAs a result of sequential traversalTreeChanged toLinear tableSo we can traverse the entire tree without repeating the list, which solves the problem of Diamond in Multi-inheritance.
For example:
Class Root: passclass A (Root): passclass B (Root): passclass C (A, B): passprint (C. _ mro _) # output result: # (<class '_ main __. C '>, <class' _ main __. a'>, <class '_ main __. B '>, <class' _ main __. root '>, <class 'object'>)
Super () actually returns a proxy's super object!
When the super () constructor is called, only a super () object is returned, and no other operations are performed.
Then, when calling this super object method, the following occurs:
For example:
Class Root: def _ init _ (self): print ('root') class A (Root): def _ init _ (self): super (). _ init _ () # is equivalent to super (A, self ). _ init __()
InA
In the constructor of, first call super () to obtainSuper object
And then callInitMethod, this is the super object will searchA
Of__mro__
List, find the first defined__init__
Method class, so we foundRoot
And then callRoot.__init__(self)
, Hereself
Yessuper()
The second parameter is automatically filled by the compiler, that isA
Of__init__
To complete__init__
Method call allocation.
Note:: In inheritance of many languages, subclass must call the constructor of the parent class to ensure that the object of the subclass canFillAttributes of the parent class! Instead of initializing a parent class object... (which I have always understood before...). Python is much better. The so-called calling of the parent class constructor is to explicitlyself
The constructor passed to the parent class,My little body is handed over to you.
Parameter description
Super ()-> same as super (_ class __, <first argument>) # <first argument> refers to the first parameter super (type) that calls the super function) -> unbound super objectsuper (type, obj)-> bound super object; requires isinstance (obj, type) super (type, type2)-> bound super object; requires issubclass (type2, type) Typical use to call a cooperative superclass method: class C (B): def meth (self, arg): super (). meth (arg) This works for class methods too: class C (B): @ classmethod def cmeth (cls, arg): super (). cmeth (arg)
That is to say, when all the following methods call super to return objects, the first parameterself
Allsuper()
Because the so-called method in Python is a function whose first parameter is self, usuallya.b()
Will implicitlya
Assignedb()
The first parameter.
Two common usage of super (): understanding of object-oriented
In fact, I think such a syntax in Python is easier to understand the nature of object-oriented, and it is better than implicit transfer in Java.this
Easier to understand.
A function is a piece of code that accepts input and returns output. the so-called method is that a function has a parameter passed implicitly. therefore, the method is a piece of code, which is shared by all instances of the class. The only difference is that the method is passed when each instance calls the method.this
Orself
Different.
What is the constructor? It is actually an instance method. It can be called only after the object is generated.__init__
The method parameter isself
Ah. When calling the constructor, the object has actually been allocated with memory. The constructor is only used for initialization, that is, assigning initial values to the memory.
The so-calledStatic variablesActuallyClass variablesIn fact, the class is also allocated with memory, which stores these variables, so the PythonClass ObjectI think it is reasonable and more intuitive than Java. as for the static method, there is no relation to the object. In essence, it is an independent function, but it is only written in the class. in PythonClassmethodIt is actually a static method, but it will depend oncls
Object, thiscls
It is a class object, but as long as you want to use this method, class objects must exist. Unlike instance objects, You need to manually instantiate them. Therefore, classmethod can also be seen as a static variable.StaticmethodIt is a real static method. It is an independent function and does not depend on any object.
The instance method in Java must depend on the object because it needs to be implicitly transmitted.this
If the object does not existthis
It cannot be implicitly, so there is no static methodthis
The instance method cannot be called, but the instance method in Python can be called through the class name.self
It cannot be passed implicitly, so it must be passed explicitly.