python 中的 super详解

Python 中的 super 详解

Python 的 super 函数是一种很特殊和重要的方法,它允许派生类调用父类的方法、属性等,本文将详细讲解 super 函数的用法及其机制。

什么是 super 函数

super 函数是 Python 中的一个内置函数,它常用于在派生类中调用其基类的方法或属性。通过 super 函数,我们可以更加方便地实现派生类与基类之间的联系,同时避免了硬编码所带来的各种问题。

super 函数的用法

super 函数最常见的用法就是调用父类的方法,其调用方式可以有两种:

  • 显式调用
  • 隐式调用

显式调用

通过显式调用 super 函数,我们可以直接指定要调用的基类和方法。例如:

class Base:
    def __init__(self):
        self.name = 'Base'

    def show(self):
        print(f'I am {self.name}')

class Derived(Base):
    def __init__(self):
        super(Derived, self).__init__()
        self.name = 'Derived'

    def show(self):
        print(f'I am {self.name}')

        # 调用 Base 类的 show 方法
        super(Derived, self).show()

在上面的示例中,Derived 类继承自 Base 类,并重写了 show 方法。在 Derived 的 show 方法中,我们通过显式调用 super 函数来调用 Base 类的 show 方法,从而实现了在派生类中调用其基类的方法。

隐式调用

通过隐式调用 super 函数,Python 会自动查找当前类的 MRO(Method Resolution Order)列表,并调用第一个碰到的基类的方法。例如:

class A:
    def show(self):
        print('A')

class B(A):
    def show(self):
        print('B')
        super().show()

class C(A):
    def show(self):
        print('C')

class D(B, C):
    pass

d = D()
d.show()

在上面的示例中,D 类继承自 B 和 C 两个类。当我们调用 d.show() 方法时,Python 会自动去查找 D 的 MRO 列表,发现 B 是其第一个基类,在执行 B 的 show 方法时,又调用了 super().show(),此时 Python 会去查找 D 的 MRO 列表中的下一个基类 C,执行 C 的 show 方法。因此最终输出结果为:

B
C

super 函数的机制

super 函数实际上是通过 C 语言实现的(这就是为什么它如此高效)。

在 Python 中,每个类都有一个 MRO(Method Resolution Order)列表,它表示了 Python 在调用该类的方法时会按照顺序搜索的列表。MRO 列表主要是通过 C3 算法来计算的,其规则如下:

  1. 如果 A 是 B 的父类,则 A 在 B 的前面;
  2. 如果 A 和 B 是同一级别的类,且 A 在 B 前面出现在 MRO(这通常是在多重继承的情况下);
  3. 如果存在多个父类同时满足以上两个条件,则按照定义时的顺序加入 MRO。

例如,如果我们有一个如下所示的类继承关系:

class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass

其 MRO 列表将按照顺序排列为 [D, B, C, A]

在 Python 2.x 版本中,我们需要手动指定调用的父类方法,例如 super(Derived, self);而在 Python 3.x 中,我们可以不传入任何参数,例如 super(),Python 会自动查找当前类的子类并调用对应的方法。实际上,这有助于解决由于硬编码所带来的各种问题。

总结

super 函数是 Python 编程中一个非常重要的函数,它可以帮助我们在派生类中调用其基类的方法,并避免硬编码所带来的各种问题。通过显式调用或隐式调用 super 函数,我们可以更加方便地实现 Python 的多重继承机制。

例如,通过在派生类 Derived 中调用 super().__init__() 方法,我们可以方便地初始化其基类 Base 中的变量;而通过在多重继承时使用 super 函数,我们可以更好地控制派生类和基类中的方法的运行顺序,从而避免出现预料之外的错误。

示例说明

这里提供两个超级函数的示例说明,可以更好地理解 super 函数的用法和机制。

示例一

下面这个示例演示了在 Python 2.x 中使用 super 函数的方法,它可以解决菱形继承所带来的问题。在 Python 2.x 中,我们需要手动指定调用的父类方法,例如 super(Derived, self)

class A(object):
    def __init__(self):
        print('A.__init__')

class B(A):
    pass

class C(A):
    def __init__(self):
        print('C.__init__')
        super(C, self).__init__()

class D(B, C):
    pass

d = D()

输出结果为:

C.__init__
A.__init__

在这个示例中,我们定义了四个类:ABCD,其中 BC 都继承自 A。在 C 类中,我们重写了 __init__ 方法,并在其中通过 super(C, self).__init__() 显式调用父类 A__init__ 方法。当我们创建 D 的实例时,Python 会自动调用 D 中的 __init__ 方法,并通过 MRO 列表执行 C 中的 __init__ 方法,最终输出正确结果。

示例二

下面的示例演示了在多重继承情况下,通过使用 super 函数可以更好地控制基类的方法调用顺序。

class A:
    def show(self):
        print('A')

class B(A):
    def show(self):
        print('B')
        super().show()

class C(A):
    def show(self):
        print('C')
        super().show()

class D(B, C):
    pass

d = D()
d.show()

输出结果为:

B
C
A

在这个示例中,D 类继承自 BC,并分别重写了 show 方法。在 BCshow 方法中,我们都使用了 super() 来调用基类 Ashow 方法。当我们创建 D 的实例并调用 show 方法时,Python 会按照 MRO 列表的顺序,从 D 开始先调用 Bshow 方法,再调用 Cshow 方法,最后调用基类 Ashow 方法。因此,最终输出结果为 B C A

阅读剩余 73%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python 中的 super详解 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 仙剑奇侠传手游查看版本号方法 1.1.13版本在哪更新

    仙剑奇侠传手游查看版本号方法攻略 1.1.13版本更新位置 要查看仙剑奇侠传手游的版本号,你可以按照以下步骤进行操作: 打开仙剑奇侠传手游应用。 在主界面上,找到并点击游戏设置按钮。通常,这个按钮会以齿轮图标的形式显示。 在设置菜单中,寻找关于游戏或版本信息的选项。这个选项通常会显示游戏的当前版本号。 点击关于游戏或版本信息选项,即可查看游戏的版本号。 示例…

    other 2023年8月3日
    00
  • 路由器之vpn应用与配置指南

    以下是关于路由器之VPN应用与配置指南的完整攻略: 什么是VPN? VPN(Virtual Private Network)是一种安全的网络连接方式,可以在公共网络上建立一个私有网络。VPN可以用于保护您的网络流量,使您的网络活动更加安全和私密。 为什么要在路由器上配置VPN? 在路由器上配置VPN可以使所有连接到该路由器的设备都受到VPN的保护。这意味着您…

    other 2023年5月6日
    00
  • python文件名批量重命名脚本实例代码

    下面详细讲解一下“python文件名批量重命名脚本实例代码”的完整攻略。 简要说明 批量重命名脚本是一种能够帮助我们快速批量修改多个文件名的工具,使用Python语言编写,具体实现思路是遍历指定的目录,对目录下的所有文件进行遍历,通过正则表达式匹配文件名,然后通过字符串的替换方法生成新的文件名,最后使用os模块中的rename方法对文件进行重命名。 实现步骤…

    other 2023年6月26日
    00
  • Python栈的实现方法示例【列表、单链表】

    下面我将详细讲解Python栈的实现方法,包括列表和单链表两种方法。 什么是栈? 在开始讲解栈的实现方法之前,我们需要先了解什么是栈。栈(Stack)是一种先进后出的数据结构,它只允许在一端进行插入和删除操作,这一端通常称为栈顶。栈被广泛应用于计算机中,例如函数调用、表达式求值、括号匹配等。 列表实现栈 在Python中,可以使用列表(list)来实现栈。列…

    other 2023年6月27日
    00
  • C++实现LeetCode(92.倒置链表之二)

    C++实现LeetCode(92.倒置链表之二)的完整攻略如下: 题目描述 给你一个单链表的头节点 head 和两个整数 left 和 right 。请你反转从位置 left 到位置 right 的链表节点,返回反转后的单链表。 解题思路 这是一道链表题目。要反转从位置left到位置right的链表节点,可以按照以下步骤进行: 先找到要反转前面的那个节点pr…

    other 2023年6月27日
    00
  • 如何创建 JavaScript 自定义事件

    下面是如何创建 JavaScript 自定义事件的完整攻略: 什么是 JavaScript 自定义事件 JavaScript 自定义事件是一种由开发者自行定义并触发的事件类型,可以在任何时候和地点触发,用于实现更加灵活的交互功能。 创建 JavaScript 自定义事件的步骤 1. 定义事件类型 首先我们需要定义一个事件类型,可以通过 new Event()…

    other 2023年6月25日
    00
  • Android 通过SQLite数据库实现数据存储管理

    以下是Android通过SQLite数据库实现数据存储管理的完整攻略: 步骤1:创建数据库和表 在Android项目的res目录下创建raw文件夹,并在该文件夹下创建一个名为database.db的SQLite数据库文件。 使用SQLite数据库管理工具(如SQLiteStudio)打开database.db文件,并创建所需的表结构。 示例1:创建用户表 C…

    other 2023年10月16日
    00
  • Sublime Text英文字母大小写怎么切换?

    Sublime Text英文字母大小写切换攻略 Sublime Text是一款功能强大的文本编辑器,提供了多种快捷键和功能来方便用户进行编辑操作。下面是关于如何在Sublime Text中切换英文字母大小写的详细攻略。 方法一:使用快捷键 Sublime Text提供了一组快捷键来快速切换英文字母的大小写。以下是常用的快捷键: 转换为大写:按下Ctrl + …

    other 2023年8月16日
    00
合作推广
合作推广
分享本页
返回顶部