欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python3 类的多继承--super调用

程序员文章站 2022-07-10 08:08:29
python3 类多继承--super调用概述一、super调用先检索兄弟类再检索父类1. 测试super调用访问顺序2. 兄弟类的必要条件二、super调用形式参考文献概述多继承的问题比较头疼,尤其是遇到了super。一、super调用先检索兄弟类再检索父类1. 测试super调用访问顺序python3 中要理解super调用的逻辑,首先要什么是python的MRO (method resolution order),即在类的继承层次中检索方法的顺序。如图1所示,设计的类结构层次中,MyBo...


概述

多继承的问题比较头疼,尤其是遇到了super。


一、super调用先检索兄弟类再检索父类

1. 测试super调用访问顺序

python3 中要理解super调用的逻辑,首先要什么是python的MRO (method resolution order),即在类的继承层次中检索方法的顺序。如图1所示,设计的类结构层次中,MyBook类有两个父类ToolBook和ScienceBook。ToolBook和ScienceBook为兄弟关系,它们有共同的子类和父类。从代码的输出结果可以看出MyBook类super调用先访问第一个父类ToolBook,然后ToolBook的super调用访问其兄弟类ScienceBook,最后ScienceBook的super调用访问其父类Book。

图1 类的结构层次

代码块1

class Book(object):
    """
    书的基类
    """

    def __init__(self, book_id):
        self._id = book_id
        print('初始化Book')

    def print(self):
        """
        打印信息
        :return:
        """
        print('Book')
        print('id:{}'.format(self._id))


class ToolBook(Book):
    """
    工具类书
    """

    def __init__(self, book_id, name):
        print('开始初始化ToolBook')
        super(ToolBook, self).__init__(book_id)
        self._name = name
        print('初始化完成ToolBook')

    def print(self):
        """
        打印信息
        :return:
        """
        print('ToolBook')
        print('id:{}'.format(self._id))


class ScienceBook(Book):
    """
    科学类书
    """

    def __init__(self, book_id):
        print('开始初始化ScienceBook')
        super(ScienceBook, self).__init__(book_id)
        print('初始化完成ScienceBook')

    def print(self):
        """
        打印信息
        :return:
        """
        print('ScienceBook')
        print('id:{}'.format(self._id))


class MyBook(ToolBook, ScienceBook):
    """
    我感兴趣的书籍类型
    """

    def __init__(self, book_id, name):
        print('开始初始化MyBook')
        super(MyBook, self).__init__(book_id, name)
        print('初始化完成MyBook')

    def print(self):
        """
        打印信息
        :return:
        """
        print('MyBook')
        super().print()


if __name__ == '__main__':
    # 类的mro列表查询
    print('类MyBook的mro列表:{}'.format(MyBook.mro()))
    print('------------------')

    # 调用初始化函数
    python_book = MyBook('ASW123', 'python_book')
    print('------------------')
    # 类的函数调用
    python_book.print()
    print('------------------')

输出结果为:

类MyBook的mro列表:[<class '__main__.MyBook'>, <class '__main__.ToolBook'>, <class '__main__.ScienceBook'>, <class '__main__.Book'>, <class 'object'>]
------------------
开始初始化MyBook
开始初始化ToolBook
开始初始化ScienceBook
初始化Book
初始化完成ScienceBook
初始化完成ToolBook
初始化完成MyBook
------------------
MyBook
ToolBook
id:ASW123
------------------

2. 兄弟类的必要条件

将【代码块1】MyBook类修改为【代码块2】,取消对ScienceBook类的继承。那么此时ToolBook和ScienceBook不再是兄弟类,ToolBook的super调用不会再去检索ScienceBook。
将【代码块1】ScienceBook类修改为【代码块3】,ScienceBook不再从book类派生。那么此时ToolBook和ScienceBook不再是兄弟类,ToolBook的super调用不会再去检索ScienceBook。
由此可知,兄弟类必须有共同的父类和子类。此外,补充测试了给ScienceBook多加一个父类,以及增加另外一个子类,都不会影响兄弟类关系。
代码块2

class MyBook(ToolBook):
    """
    我感兴趣的书籍类型
    """

    def __init__(self, book_id, name):
        print('开始初始化MyBook')
        super(MyBook, self).__init__(book_id, name)
        print('初始化完成MyBook')

    def print(self):
        """
        打印信息
        :return:
        """
        print('MyBook')
        super().print()

输出结果为:

类MyBook的mro列表:[<class '__main__.MyBook'>, <class '__main__.ToolBook'>, <class '__main__.Book'>, <class 'object'>]
------------------
开始初始化MyBook
开始初始化ToolBook
初始化Book
初始化完成ToolBook
初始化完成MyBook
------------------
MyBook
ToolBook
id:ASW123
------------------

代码块3

class ScienceBook(object):
    """
    科学类书
    """

    def __init__(self, book_id):
        print('开始初始化ScienceBook')
        super(ScienceBook, self).__init__(book_id)
        print('初始化完成ScienceBook')

    def print(self):
        """
        打印信息
        :return:
        """
        print('ScienceBook')
        print('id:{}'.format(self._id))

输出结果:

类MyBook的mro列表:[<class '__main__.MyBook'>, <class '__main__.ToolBook'>, <class '__main__.Book'>, <class '__main__.ScienceBook'>, <class 'object'>]
------------------
开始初始化MyBook
开始初始化ToolBook
初始化Book
初始化完成ToolBook
初始化完成MyBook
------------------
MyBook
ToolBook
id:ASW123
------------------

二、super调用形式

  1. super(Type, 实例)
  2. super()
    第1种调用方式中实例必须是Type类型或其子类,第2种调用方式会将当前类指定为Type,并将self指定为实例。
    新增一个类如【代码块4】,super可以绕过直接基类访问间接基类。

代码块4

class YouBook(ToolBook, ScienceBook):
    """
    我感兴趣的书籍类型
    """

    def __init__(self, book_id):
        print('开始初始化YouBook')
        super(ScienceBook, self).__init__(book_id)
        print('初始化完成YouBook')

    def print(self):
        """
        打印信息
        :return:
        """
        print('YouBook')
        super().print()

参考文献

  1. python3菜鸟教程

本文地址:https://blog.csdn.net/naibula/article/details/109615198

相关标签: python