In-depth parsing of the use of super keywords in python programming

Source: Internet
Author: User
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[,,,
 
   
  
    
   
     
    
     
      
     ]
    
     
   
    
  
   
 
  
  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.