Python Multi-Inheritance detailed

Source: Internet
Author: User
Class A (object):    # A must is New-style class   def __init__ (self):    print "Enter A"    print "Leave a"  clas S B (c):     # A-C   def __init__ (self):    print "Enter B"    super (b, self). __init__ ()    print "Leave B"

In our impression, for super (b, self). __init__ () is the understanding that super (b, self) first finds the parent class of B (that is, Class A), then converts the object of Class B to the object of Class A, and then the Class A object "converted" calls its own __ The init__ function.

One day a colleague designed a relatively complex class architecture (let's not care if this class system is designed to be reasonable, just consider this example as a topic), the code is as follows

Code Snippet 4:

Class A (object):    def __init__ (self):        print "Enter a"        print "Leave a"  class B (object):    def __init__ (self):        print "Enter B"        print "Leave B"  class C (A):    def __init__ (self):        print "Enter C"        super (C, self). __init__ ()        print "Leave C"  Class D (A):    def __init__ (self):        print "Enter D"        Super (D , self). __init__ ()        print "Leave D"        class E (B, C):        def __init__ (self):        print "Enter E"        b.__ Init__ (self)        c.__init__ (self)        print "Leave E"  class F (E, D):    def __init__ (self):        print " Enter F "        e.__init__ (self)        d.__init__ (self)        print" Leave F "

f = f (), the result is as follows:

Enter F Enter e enter B Leave B enter C Enter D Enter a leave a leave D leave C leave E enter D Enter a leave a leave D le Ave F

Obviously, the initialization functions of Class A and Class D are called repeatedly 2 times, which is not the result we expect! The result we expect is that at most only the initialization function of Class A is called 2 times-in fact, this is a problem that a multi-inheritance class system must face. We draw the class system of code snippet 4, such as:

Object
| \
| A
| / |
B C D
\ / |
E |
\ |
F

In our understanding of super, we can see that when invoking the initialization function of Class C, the initialization function of Class A is called, but the initialization function of Class D is actually called. Good one weird problem!

That is, the MRO records a sequence of class types for all the base classes of a class. Review the MRO records and discover that there are 7 elements, and 7 class names are:

F E B C D A Object

This explains why super (C, self) is used in c.__init__. __INIT__ () invokes the initialization function of Class D.???

Let's rewrite code snippet 4 to:

Code Snippet 5:

Class A (object):    def __init__ (self):        print "Enter a"        super (A, self). __init__ ()  # new        print "leave A "  class B (object):    def __init__ (self):        print" Enter B "        super (b, self). __init__ ()  # New        Print "Leave B"  class C (A):    def __init__ (self):        print "Enter C"        super (C, self). __init__ ()        Print "Leave C"  class D (A):    def __init__ (self):        print "Enter D"        super (d, Self). __init__ ()        Print "Leave D"        class E (B, C):        def __init__ (self):        print "Enter E"        super (E, self). __init__ ()  # change        print ' Leave e '  class F (E, D):    def __init__ (self):        print ' Enter F '        super (F, self). __ Init__ ()  # change        print "Leave F"

f = f (), execution result:

Enter F Enter e enter B Enter C Enter D Enter a leave a leave D leave C leave B leave E leave F

As can be seen, the initialization of F not only completes all calls to the parent class, but also guarantees that the initialization function of each parent class is called only once.

Summary

1. Super is not a function, it is a class name, like Super (B, self) actually called the Super class initialization function,
produced a Super object;
2. The Super class initialization function does not do anything special, but simply records the class type and the concrete instance;
3. Super (B, self). The invocation of Func is not a Func function that invokes the parent class of the current class;
4. Python's multi-inheritance class ensures that functions of each parent class are called through the MRO method, and that each parent class function
Call only once (if each class uses Super);
5. Mixing super and unbound functions is a risky behavior, which can cause the parent class function that should be called to not call or a
A parent class function is called multiple times.

Some more in-depth questions: You can see that the order of the elements in print f.__mro__ is F E B C D A object, which is the base class lookup order for F, as to why this is the order, and how the python built-in multiple inheritance order is implemented, This involves the implementation of the MRO sequence, which is an algorithm called C3 in the later version of Python 2.3, which is described in the next blog post.

  • 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.