Detailed explanation of Python inheritance and method resolution order (MRO) | Examples and use of super() function

inherit

Inheritance is an important concept in object-oriented programming. Through inheritance, we can allow one class to obtain properties and methods in other classes, avoid writing repetitive code, and comply with the Open and Closed Principle (OCP). Inheritance is a common way to extend a class.

Define a class Animal

We first define a class Animal, which has two methods run() and sleep(), indicating that the animal can run and sleep.

class Animal:
    def run(self):
        print('动物会跑~~~')

    def sleep(self):
        print('动物睡觉~~~')

Define a class Dog

Now, we want to define a class Dog, which can not only run and sleep, but also bark. We can directly modify the Animal class and add the bark() method to it, but this will violate OCP principles. A better way is through inheritance .

class Dog(Animal):
    def bark(self):
        print('汪汪汪~~~') 

    def run(self):
        print('狗跑~~~~')   

In the above code, we use class Dog(Animal):to specify that the Dog class inherits from the Animal class. In this way, the Dog class can directly obtain the properties and methods of the Animal class. We can also override methods in the Animal class, such as redefining the run() method in the Dog class.

Create objects and call methods

Now we can create an object of Dog class d = Dog()and call its methods such as d.run(), d.sleep()and d.bark().

d = Dog()
d.run()  # 输出:狗跑~~~~
d.sleep()  # 输出:动物睡觉~~~
d.bark()  # 输出:汪汪汪~~~

relationship between classes

By using inheritance, we can establish hierarchical relationships between classes. When creating a class, if the parent class is omitted, the default parent class is object. objectIs the parent class of all classes, so all classes inherit from object.

class Person(object):
    pass

We can issubclass()check if a class is a subclass of another class using functions like issubclass(Animal, Dog)return Falseand issubclass(Animal, object)return True.

We can also use isinstance()the function to check if an object is an instance of a class. If this class is the parent class of this object, it will also be returned True. All objects are objectinstances of .

print(isinstance(d, Dog))  # 输出:True
print(isinstance(d, Animal))  # 输出:True
print(isinstance(d, object))  # 输出:True
print(isinstance(print, object))  # 输出:True

Inheritance makes the relationship between classes clearer and facilitates code reuse and extension.

multiple inheritance

In addition to single inheritance, Python also supports multiple inheritance, that is, a subclass can inherit properties and methods from multiple parent classes. This provides us with greater flexibility, making it easier to organize and reuse code.

Define a class Hashiqi

Suppose we also have a class Hashiqi, which represents a special kind of dog. In addition to the basic behavior of a dog, it also has its own unique method fan_sha(), which represents a silly husky.

class Hashiqi(Dog):
    def fan_sha(self):
        print('我是一只傻傻的哈士奇')

In the above code, we define a Hashiqi class, which inherits from the Dog class. Therefore, the Hashiqi class can not only have the properties and methods in the Animal class and Dog class, but also has its own unique fan_sha() method.

Create objects and call methods

Now we can create objects of Hashiqi class h = Hashiqi()and call its methods such as h.run(), h.sleep(), h.bark()and h.fan_sha().

h = Hashiqi()
h.run()  # 输出:狗跑~~~~
h.sleep()  # 输出:动物睡觉~~~
h.bark()  # 输出:汪汪汪~~~
h.fan_sha()  # 输出:我是一只傻傻的哈士奇

Through multiple inheritance, we can achieve more flexible and complex relationship class structures. When creating a subclass, you only need to specify multiple parent classes, and the subclass can directly obtain the properties and methods in all parent classes, thus reducing code redundancy.

Inheritance is one of the important features of object-oriented programming. It can improve the readability, maintainability and scalability of code and comply with the opening and closing principle. When designing classes, we should fully consider inheritance relationships and follow good code organization and design principles.

When a class inherits from multiple parent classes, you may encounter naming conflicts. For example, if two parent classes have a method or property with the same name, there will be ambiguity when calling that name in the child class. To solve this problem, Python provides Method Resolution Order (MRO for short).

Method Resolution Order (MRO)

In Python, each class has a method resolution order, which is the order in which the parent classes it inherits from are searched. You can use 类名.__mro__or 类名.mro()to view the method resolution order. Below is an example:

class A:
    def method(self):
        print("A")

class B(A):
    def method(self):
        print("B")

class C(A):
    def method(self):
        print("C")

class D(B, C):
    pass

print(D.__mro__)
print(D.mro())

Running the above code will output the following results:

(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

As can be seen from the output results, the method resolution order is D -> B -> C -> A -> object. That is to say, when a method is called on an instance of class D method(), it will be searched in this order and the first matching method will be executed.

super() function

The super() function is a way to call a parent class method. You can use super().方法名()the form to call methods of the parent class without explicitly specifying the name of the parent class. for example:

class A:
    def method(self):
        print("A")

class B(A):
    def method(self):
        super().method()
        print("B")

b = B()
b.method()

The output is:

A
B

In the above code, class B inherits from class A, and uses super().method() in its own method() method to call the method() method in the parent class A, and then prints "B".

Using the super() function can ensure that the methods of the parent class are called sequentially in the order of method resolution during multiple inheritance, thereby avoiding naming conflicts and ambiguities.

When there is diamond inheritance in multiple inheritance, in order to avoid repeated method calls and redundant code, Python uses the C3 linearization algorithm to determine the method resolution order (MRO).

C3 linearization algorithm

The C3 linearization algorithm generates a linearization list that satisfies the following conditions by merging the linearization orders of multiple parent classes:

  1. Subclasses always precede parent classes.
  2. If a class appears earlier in the list, then all of its parent classes also appear earlier.
  3. If multiple parent classes follow a class, their order remains unchanged.

In this way, in the method resolution sequence, the method of each class will only be called once, avoiding repeated calls and redundant code.

Example

Here is an example of diamond inheritance:

class A:
    def method(self):
        print("A")

class B(A):
    pass

class C(A):
    def method(self):
        print("C")

class D(B, C):
    pass

d = D()
d.method()

In the above code, class D inherits from B and C, and both B and C inherit from A. When we create an instance of D and call method()the method, the method resolution order obtained according to the C3 linearization algorithm is D -> B -> C -> A, so the output result is "C".

super() function and diamond inheritance

When using the super() function, Python will call the methods of the parent class according to the method resolution order determined by MRO. In the case of diamond inheritance, the super() function will call the methods of each parent class in sequence in MRO order, and ensure that each method is called only once.

class A:
    def method(self):
        print("A")

class B(A):
    def method(self):
        super().method()
        print("B")

class C(A):
    def method(self):
        super().method()
        print("C")

class D(B, C):
    pass

d = D()
d.method()

Running the above code, the output is:

A
C
B

In this example, the method resolution order of class D is D -> B -> C -> A. When the method is called d.method(), super().method() will call the method() methods of classes B, C, and A in sequence. Through MRO, each class method will only be called once, avoiding repeated calls and redundant code.

Classic and new styles

In Python 2.x versions, there is the concept of classic classes and new-style classes. Classic classes are classes that do not explicitly inherit from object, while new-style classes are classes that explicitly inherit from object.

In classic classes, Python uses a depth-first search method to resolve the order of method calls. There are some problems with this method, such as repeated method calls and the inability to implement method resolution order when multiple inheritance is implemented.

In new-style classes, Python uses the C3 linearization algorithm to resolve the order of method calls. This method can ensure that the method is only called once, and solves the problem of uncertain method resolution order during multiple inheritance.

In order to be better compatible with old and new versions of Python, a special syntax was introduced in Python 2.3, which is the form used when defining classes class ClassName(object):, thereby defining all classes as new-style classes.

In the Python 3.x version, all classes are defined as new-style classes by default, and there is no need to explicitly inherit from object.

Summarize

Multiple inheritance in Python gives programmers more flexible design choices, but it also brings some challenges. In order to avoid naming conflicts and ambiguities, the method resolution order (MRO) needs to be correctly set in multiple inheritance to ensure the correctness and efficiency of method calls.

Python3.x has defined all classes as new-style classes by default and uses the C3 linearization algorithm to solve the problem of multiple inheritance. There is no need to pay special attention to the setting of MRO.

In Python, diamond inheritance means that a subclass inherits from two classes with a common parent class at the same time, forming a diamond-shaped inheritance structure. This inheritance structure can cause problems such as repeated method calls and redundant code.

In order to solve the problems caused by diamond inheritance, Python uses the C3 linearization algorithm to determine the method resolution order (Method Resolution Order, MRO). Specific steps are as follows:

  1. Generate a topologically sorted list (DAG) according to the declaration order of the classes.
  2. In a topologically sorted list, each node's list of parents is checked and the position of its parent is moved in front of itself. In this way, it is guaranteed that the subclass comes before the parent class.
  3. For the case where multiple parent classes appear after the same node at the same time, their order in the base class list needs to remain unchanged.

By using the C3 linearization algorithm, Python can avoid the problems of repeated method calls and redundant code. In addition, Python automatically calculates MRO during class definition and stores it in special attributes __mro__for developers to view.

It should be noted that in actual use, when there is diamond inheritance, super()problems can be avoided by properly designing the inheritance relationship of the class and using functions. Reasonable use of polymorphism, composition and other technologies can also reduce the complexity caused by inheritance.

Recommended Python boutique columns


Basic knowledge of python (0 basic introduction)

[Python basic knowledge] 0.print() function
[python basic knowledge] 1. Data types, data applications, data conversion
[python basic knowledge] 2. if conditional judgment and condition nesting
[python basic knowledge] 3.input() Functions
[Basic knowledge of python] 4. Lists and dictionaries
[Basic knowledge of python] 5. For loops and while loops
[Basic knowledge of python] 6. Boolean values ​​and four types of statements (break, continue, pass, else)
[Basic knowledge of python] 7. Practical operation - Use Python to implement the "Word PK" game (1)
[Python basic knowledge] 7. Practical operation - Use Python to implement the "Word PK" game (2)
[Python basic knowledge] 8. Programming thinking: how to Solving problems - Thinking Chapter
[Basic Knowledge of python] 9. Definition and calling of functions
[Basic Knowledge of Python] 10. Writing programs with functions - Practical Chapter
[Basic Knowledge of Python] 10. Using Python to implement the rock-paper-scissors game - Function Practice Operation Chapter
[Python Basics] 11. How to debug - Common error reasons and troubleshooting ideas - Thinking Chapter
[Python Basics] 12. Classes and Objects (1)
[Python Basics] 12. Classes and Objects (2)
[Python Basics] Knowledge] 13. Classes and objects (3)
[Basic knowledge of python] 13. Classes and objects (4)
[Basic knowledge of python] 14. Building a library management system (practical operation of classes and objects)
[Basic knowledge of python] 15. Coding basic knowledge
[Basic knowledge of python] 16. Fundamentals of file reading and writing and operations
[Basic knowledge of python] 16. Python implementation of "Ancient poem dictation questions" (File reading, writing and coding - practical operation)
[Basic knowledge of python] 17. The concept of modules and How to introduce
[python basics] 18. Practical operation - using python to automatically send mass emails
[python basics] 19. Product thinking and the use of flow charts - thinking
[python basics] 20. python implementation of "what to eat for lunch" ( Product Thinking - Practical Operation)
[Basic knowledge of python] 21. The correct way to open efficiently and lazily - Graduation
[python file processing] Reading, processing and writing of CSV files
[python file processing] Excel automatic processing (using openpyxl)
[python file processing]-excel format processing


python crawler knowledge

[python crawler] 1. Basic knowledge of crawlers
[python crawler] 2. Basic knowledge of web pages
[python crawler] 3. First experience with crawlers (BeautifulSoup analysis)
[python crawler] 4. Practical crawler operation (dish crawling)
[python crawler] 5 .Practical crawler operation (crawling lyrics)
[python crawler] 6. Practical crawler operation (requesting data with parameters)
[python crawler] 7. Where is the crawled data stored?
[python crawler] 8. Review the past and learn the new
[python crawler] 9. Log in with cookies (cookies)
[python crawler] 10. Command the browser to work automatically (selenium)
[python crawler] 11. Let the crawler report to you on time
[python crawler] 12. Build your crawler army
[python crawler] 13. What to eat without getting fat (crawler practical exercise)
[python crawler] 14. Scrapy framework explanation
[python crawler] 15. Scrapy framework practice (popular job crawling Take)
[python crawler] 16. Summary and review of crawler knowledge points

Guess you like

Origin blog.csdn.net/qq_41308872/article/details/132852073