Python multiple inheritance raises the question--the super

Source: Internet
Author: User

Do not say a lot of nonsense to do in advance of the previous diagram, this picture with Win7 under the drawing tool painting, of course, this is not the focus

One thing that needs to be clear is:

Any class, by default and implicitly inherits the object class (the root Class), in the diagram above, the Transformers class inherits both the car and the ship class. Then car and ship implicitly inherit the object class, note that this object class is not my own definition of

It's python.


According to the diagram above, write the code

class car:     #描述汽车     call_car_record = 0  #记录调用次数     def __init__ (Self, car_name):         self.car_name = car_name    def land_run (self):         print ("{0} run on land". Format (self.car_name))          self.call_car_record += 1class Ship:     #描述轮船     call_ship_record = 0  #记录调用次数     def __init__ ( Self, ship_name):         self.ship_name = ship_name     def running_in_sea (self):         print ("{ 0} running in the sea ". Format (self.ship_name))          self.call_ship_record += 1class transformers (car, ship):     #变形金刚      call_tran_record = 0  #记录调用次数     def __init__ (Self, car_name,  ship_name, tran_name):         car.__init__ (Self, car_ Name)         ship.__init__ (self, ship_name)          self.tran_name = tran_name    def  Transfiguration (self):         print ("{0} start  Transfiguration ... ". Format (self.tran_name))         self.call_tran_ record += 1if __name__ ==  ' __main__ ':    t =  Transformers ("BYD",  "gz01",  "Toby")     t.land_run ()      T.running_in_sea ()     t.transfiguration () &nbsP;   print (T.call_tran_record, t.call_car_record, t.call_ship_record) "" "Output result:     byd run on land    gz01 running in the  sea    toby start Transfiguration...    1 1  1 "" "

So, the above code, the problem is that I am in the description, that is, the object class is implicitly called two times, but is not aware of, but does exist.



Ok!!! I want to prove this problem and confirm that it was not called two times. I'm going to take another picture, as follows:

The above figure, is the legend of the masonry inheritance, what is the inheritance of masonry? Just the inheritance view of this class looks like masonry, and of course it's just my understanding.

If you use this diagram to prove that BaseClass will not be called 2 times, then it needs to be converted into code. The code is as follows:

class baseclass:    num_base_calls = 0  #记录基类被调用次数      def work (self):         print ("Work method of  calling base class ")         self.num_base_calls + = 1class aclass (baseclass):    num_aclass_calls = 0  #记录被调用次数     def work (self):         baseclass.work ( Self)         print ("Work method of calling aclass  class ")         self.num_aclass_calls += 1class  Bclass (baseclass):    num_bclass_calls = 0  #记录被调用次数      Def work (self):         baseclass.work (self)          priNT ("Work method of calling bclass class")          self.num_bclass_calls += 1class cclass (aclass, bclass):     num_ cclass_calls = 0  #记录被调用次数     def work (self):         aclass.work (self)         bclass.work (self)         print ("Calling work method on cclass")         self.num_cclass_calls += 1if __name__ ==   ' __main__ ':     c = cclass ()     c.work ()      print (C.num_cclass_calls, c.num_aclass_calls, c.num_bclass_calls, c.num_base_calls) "" Result output:work method of calling base classwork method of calling  Aclass classwork method of calling base classwork method of calling bclass  Classcalling work method on cclass1 1 1 2 "" "

From the output of the results, BaseClass really was called two times, this base class is my own definition, this is not an implicit call, is blatant in the call Ah!!!

How to solve this problem? Professionals say with super, I do not believe, so I tried a bit, the improved code is as follows:

class baseclass:    num_base_calls = 0  #记录基类被调用次数      def work (self):         print ("Work method of  calling base class ")         self.num_base_calls + = 1class aclass (baseclass):    num_aclass_calls = 0  #记录被调用次数     def work (self):         super (). Work ()         print ("work method of calling aclass  Class ")         self.num_aclass_calls += 1class bclass ( BaseClass):    num_bclass_calls = 0  #记录被调用次数     def  work (self):         super (). Work ()          print ("Work&nbsP;method of calling bclass class ")         self.num _bclass_calls += 1class cclass (aclass, bclass):     num_cclass_calls  = 0  #记录被调用次数     def work (self):         super (). Work ()         print ("Calling work method  on cclass ")         self.num_cclass_calls += 1if  __name__ ==  ' __main__ ':     c = cclass ()      C.work ()     print (C.num_cclass_calls, c.num_aclass_calls, c.num_bclass_calls,  c.num_base_calls) "" "Output Result: Work method of calling base classwork method  of calling BClass classwork method of calling AClass  Classcalling work method&nbSp;on cclass1 1 1 1 "" " 

It turns out that the base class of BaseClass is really only called once, which is the power of super. However, whether you believe it or not, I believe it anyway.

That analysis of his sequence of calls, I drew a diagram:

See Figure Analysis:
1, Cclass Class of work () method called the Super.work, is actually quoted Aclass.work ()
2, in Aclass.work (), called the Super.work (), this time is referred to Bclass.work (), and not Baseclass.work (), which is called the next method
3, then call the Super.work () method in Bclass.work (), this is the time to call the Baseclass.work () method



Now go back to the first example of multiple inheritance, in the case of multiple inheritance, in the __init__ method of the Transformers class, in order to implement a __init__ () method that can invoke two parent classes

My initial practice was to write two calls respectively. The problem here is that there are two initialization methods for the parent class to invoke, and different parameters are required.

Well, I started out as the following code so, not not, but not my goal, I am a pursuit of perfection, so I decided to improve it, but also use super to do

Class Transformers (Car, ship): #变形金刚 call_tran_record = 0 def __init__ (self, car_name, Ship_name, Tran_name): Car.__init__ (self, car_name) #调用Car类的初始化方法 ship.__init__ (self, ship_name) #调用Ship类的初始化方法 Self.tran_name = Tran_name



The improved code is as follows:

class car:     #描述汽车     call_car_record = 0  #记录调用次数     def __init__ (Self, car_name=none, **kwargs):         super (). __init__ (**kwargs)         self.car_ Name = car_name    def land_run (self):         print ("{0} run on land". Format (self.car_name))          self.call_car_record += 1class Ship:     #描述轮船      call_ship_record = 0  #记录调用次数     def __init__ (self, ship_ Name=none, **kwargs):         super (). __init__ (**kwargs)          self.ship_name = ship_name    def  running_in_sea (self): &NBSp;       print ("{0} running in the sea". Format ( Self.ship_name))         self.call_ship_record += 1class  transformers (car, ship):     #变形金刚     call_tran_record  = 0  #记录调用次数     def __init__ (Self, tran_name=none, **kwargs):         super (). __init__ (**kwargs)          self.tran_name = tran_name    def transfiguration (self):         print ("{0} start transfiguration ...". Format (self.tran_name ))         self.call_tran_record += 1if __name__ ==   ' __main__ ':     t = transformers (tran_name= "Toby",  car_name= "BYD",  ship_name= "QQ")      t.land_run ()     t.running_in_sea ()     t.transfiguration ()     print (T.call_tran_record, t.call_car_record, t.call_ship_record)


How do you analyze the order in which it is executed? Please use the "next method" idea to understand it.


Finally, let's summarize the super's cool.

1. In the inheritance hierarchy of a class, you only want to invoke the next method instead of the parent class.

2. Super's goal is to solve complex multiple inheritance problems (the base class is called two times the problem)

3. Super is an absolute guarantee that each method is executed only once in the inheritance hierarchy of a class

Python multiple inheritance raises the question--the super

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.