浅谈Python面向对象中的继承与mro

简介: 浅谈Python面向对象中的继承与mro

继承

python中的继承的含义就是其字面意思, 子类继承父类中的属性和方法, 且可以同时继承多个父类, 子类下面还可以再继续划分子类的子类。形成一种树形的结构, 最顶部的类叫做基类, 基类下面的子类等被称为派生类

在子类中可以定于跟父类中名称相同的方法和属性, 这些行为被称之为重写(重构), 在调用时优先调用当前类中的方法, 如果在当前类中搜索不到则树形结构向上递归查找。

PS: Python中所有的类都默认继承一个基类 Object


class A: # 等价于 class A(Object):
    def __init__(self, name):
        self.name = name
    def run(self):
        return "running with class A"
class B:
    def __init__(self, name):
        self.name = name
    def run(self):
        return "running with class B"
class C(B, A):
    def space(self):
        pass
# a既是C的实例, 也是A,B的实例
a = C("takahashi")
# 按mro结构查找方法
print(a.run())


>>> running withclassB

Mro

Python的MRO即Method Resolution Order(方法解析顺序),即在调用方法时,会对当前类以及所有的基类进行一个搜索,以确定该方法之所在,而这个搜索的顺序就是MRO。

Mro搜索原则:

  1. 子类永远在父类前面
    2. 如果有多个父类,则按mro列表中的顺序被调用
    3. 如果下一个类中存在两个合法的选择, 则只选择第一个

如果需要查看类的mro调用顺序只需要打印ClassName.mro()即可, 返回一个列表。

示例代码

class A:
    def __init__(self):
        print("Class A now is start!")
class B(A):
    def __init__(self):
        super().__init__() # 此处先调用了class A中的__init__方法
        print("Class B now is start!")
class C:
    def __init__(self):
        print("Class C now is start!")
class inherit(A, C):
    def display(self):
        print(inherit.mro())
class other_inherit(B, C):
    def display(self):
        print(other_inherit.mro())
class another_inherit(C, B):
    def display(self):
        print(another_inherit.mro())
class last_inherit(other_inherit, C):
    def display(self):
        print(last_inherit.mro())
print("----------------------cut-line-----------------------")
a = inherit()
a.display()
print("----------------------cut-line-----------------------")
b = other_inherit()
b.display()
print("----------------------cut-line-----------------------")
c = another_inherit()
c.display()
print("----------------------cut-line-----------------------")
d = last_inherit()
d.display()
print("----------------------cut-line-----------------------")


>>> ----------------------cut-line-----------------------
>>> Class A now is start!
>>> [<class '__main__.inherit'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
>>> ----------------------cut-line-----------------------
>>> Class A now is start!
>>> Class B now is start!
>>> [<class '__main__.other_inherit'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
>>> ----------------------cut-line-----------------------
>>> Class C now is start!
>>> [<class '__main__.another_inherit'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>> ----------------------cut-line-----------------------
>>> Class A now is start!
>>> Class B now is start!
>>> [<class '__main__.last_inherit'>, <class '__main__.other_inherit'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
>>> ----------------------cut-line-----------------------

super()

并非魔术方法, 但是在Python对象的创建和父类(同胞类, 下略)函数的调用中起到了至关重要的作用

函数结构

super(ClassName, Type).function(Type, [*args...])

函数作用

提供对父类或者同胞类中的方法和属性的访问

说明

在Python3中super默认值是当前继承的父类名, 如果有多个继承的父类, 则取第一个。

如果继承的多个父类中都有着相同的方法则只调用第一个继承的父类中的那个方法。


class A:
    def __init__(self):
        print("Class A now is start!")
class B(A):
    def __init__(self):
        super().__init__()
        print("Class B now is start!")
class C:
    def __init__(self):
        print("Class C now is start!")
class D:
    def __init__(self):
        print("Class D now is start!")
class inherit(A, C):
    def display(self):
        print(inherit.mro())
class other_inherit(B, C):
    def display(self):
        print(other_inherit.mro())
class another_inherit(A, D):
    def display(self):
        print(another_inherit.mro())
class last_inherit(other_inherit, C):
    def display(self):
        print(last_inherit.mro())
class test(last_inherit, another_inherit):
    def display(self):
        print(super().display())
print("----------------------cut-line-----------------------")
a = inherit()
a.display()
print("----------------------cut-line-----------------------")
b = other_inherit()
b.display()
print("----------------------cut-line-----------------------")
c = another_inherit()
c.display()
print("----------------------cut-line-----------------------")
d = last_inherit()
d.display()
print("----------------------cut-line-----------------------")
e = test()
e.display()
print("----------------------cut-line-----------------------")


>>> ----------------------cut-line-----------------------
>>> Class A now is start!
>>> [<class '__main__.inherit'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
>>> ----------------------cut-line-----------------------
>>> Class A now is start!
>>> Class B now is start!
>>> [<class '__main__.other_inherit'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
>>> ----------------------cut-line-----------------------
>>> Class A now is start!
>>> [<class '__main__.another_inherit'>, <class '__main__.A'>, <class '__main__.D'>, <class 'object'>]
>>> ----------------------cut-line-----------------------
>>> Class A now is start!
>>> Class B now is start!
>>> [<class '__main__.last_inherit'>, <class '__main__.other_inherit'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
>>> ----------------------cut-line-----------------------
>>> Class A now is start!
>>> Class B now is start!
>>> [<class '__main__.last_inherit'>, <class '__main__.other_inherit'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
>>> None
>>> ----------------------cut-line-----------------------

由上可得, 如果同时继承了多个父类, 则在调用父类中的方法时只会调用第一个继承的父类中的方法。

目录
相关文章
|
8天前
|
Python
你真的会面向对象吗!解密Python“魔术方法”
你真的会面向对象吗!解密Python“魔术方法”
16 0
|
2月前
|
Python
Python进阶第一篇(Python的面向对象)
Python进阶第一篇(Python的面向对象)
|
3月前
|
存储 算法 安全
Python编程实验六:面向对象应用
Python编程实验六:面向对象应用
73 1
|
3月前
|
人工智能 自然语言处理 开发者
Python基础教程——面向对象
Python基础教程——面向对象
|
7天前
|
算法 Python
python多继承的3C算法是什么?怎么用?
有很多地方都说python多继承的继承顺序,是按照深度遍历的方式,其实python多继承顺序的算法,不是严格意义上的深度遍历,而是基于深度遍历基础上优化出一种叫3C算法
|
18天前
|
安全 算法 Go
Python面向对象的三大特性
python面向对象编程(OOP)的三大特性是封装、继承和多态。这些特性共同构成了OOP的基础,使得软件设计更加灵活、可维护和可扩展。
14 3
|
23天前
|
数据采集 Java C语言
Python面向对象的高级动态可解释型脚本语言简介
Python是一种面向对象的高级动态可解释型脚本语言。
17 3
|
2月前
|
Python
Python面向对象进阶:深入解析面向对象三要素——封装、继承与多态
Python面向对象进阶:深入解析面向对象三要素——封装、继承与多态
|
2月前
|
Python
Python面向对象基础与魔法方法详解
Python面向对象基础与魔法方法详解
|
2月前
|
Python
python面向对象
python面向对象
16 1