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

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

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

相关文章

  • python如何实现递归转非递归

    当一个算法或者函数使用递归时,它会在内存中伸展出一条递归链,最后达到解决问题的结束点,这条链往往是以下几个步骤的简单重复: 检查基本条件。 执行一些操作或者递归。 3. 更改输入参数。 递归可以使代码更加简洁和容易理解,但是递归链太长时,会消耗大量的内存资源,并且很难理清楚所有的递归过程,所以我们有必要将递归函数转换成非递归函数。 下面介绍两种将递归函数转化…

    other 2023年6月27日
    00
  • 你可能不知道的Vim使用小技巧

    你可能不知道的Vim使用小技巧 Vim 是程序员的福音,但 Vim 的强大功能也常常让人感到震惊。为了帮助大家更好地使用 Vim,本文将为大家介绍一些 Vim 中你可能不知道的小技巧。 1. 使用 . 重复上一次操作 在 Vim 中,你可能经常需要重复某个操作,例如删除多行代码、重复上一次修改等。你可以使用.来简单实现这个操作。比如你删除了三行代码,想再删除…

    other 2023年6月26日
    00
  • Java设计模式之责任链模式的示例详解

    Java设计模式之责任链模式的示例详解 什么是责任链模式 责任链模式是一种行为型设计模式,设计思路是将一个请求同一个处理的对象组成一条链,当请求在链上不断传递并处理直到被处理完毕。责任链模式可以避免请求的直接发起者和接受者之间的耦合关系,同时使得请求可以被多个对象依次进行处理。 如何实现责任链模式 责任链模式包含两个重要的角色:抽象处理者和具体处理者。抽象处…

    other 2023年6月27日
    00
  • 详解linux中nginx启动 重启 关闭命令

    在Linux中,Nginx是一个常见的Web服务器和反向代理服务器。本文将为大家详细讲解Nginx的启动、重启和关闭命令。 启动Nginx 要启动Nginx,请使用以下命令: sudo systemctl start nginx 在启动之前,您可能需要先检查nginx配置文件是否正确,以确保成功启动。可以通过以下命令进行检查: sudo nginx -t 如…

    other 2023年6月27日
    00
  • 使用PyInstaller 打包配置文件

    使用PyInstaller打包配置文件的完整攻略如下: 1. 安装PyInstaller 首先需要安装PyInstaller工具,可以通过pip方式进行安装,命令如下: pip install pyinstaller 2. 准备代码和配置文件 需要准备好需要打包的代码,以及需要使用的配置文件。通常,配置文件需要放置在代码的同级目录下,并使用相对路径来引用。 …

    other 2023年6月25日
    00
  • vue3简单封装input组件和统一表单数据详解

    下面就“vue3简单封装input组件和统一表单数据详解”的完整攻略进行详细讲解。该攻略主要讲解在Vue3中封装简单的Input组件,并用一个统一的表单数据进行数据处理。 1. Vue3中封装简单的Input组件 在Vue3中,我们可以通过defineComponent函数定义一个组件。下面是一个简单的Input组件的代码: import { defineC…

    other 2023年6月25日
    00
  • javascript轮播图怎么实现

    以下是详细讲解“JavaScript轮播图怎么实现的完整攻略”的标准Markdown格式文本,包含两个示例说明: JavaScript轮播图实现攻略 轮播图是Web开发中常用的交互组件之一,可以用于展示图片、等。本攻略将介绍如何使用JavaScript实现轮播图。 步骤一:HTML结构 首先,需要在HTML中定义轮播图的结构。可以使用<div>元…

    other 2023年5月10日
    00
  • maya怎么制作一个四条腿的椅子模型?

    制作椅子模型可以分为以下步骤: 设置参考图片 可以找到一张具有椅子四条腿特征的参考图片。在Maya的3D视图中,可以使用“Create Camera from View”命令创建一个相机视图。然后,在属性编辑器(Attribute Editor)中,找到相机的“Image Plane”(图像平面)选项。可以选择该选项的“Browse”按钮来选择参考图片。此外…

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