鱼C论坛

 找回密码
 立即注册
查看: 1770|回复: 5

[已解决]super函数

[复制链接]
发表于 2023-8-3 21:08:45 | 显示全部楼层 |阅读模式
2鱼币
class A:
    def say(self):
        super().say()
        print("FishA")


class B:
    def say(self):
        print("FishB")


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


class D(B):
    def say(self):
        super().say()
        print("FishD")


class E(C, D):
    def say(self):
        super().say()
        print("FishE")


e = E()
e.say()

为什么打印的顺序是这个样子,求救
最佳答案
2023-8-3 21:08:46
这是因为Python使用了C3线性化算法来确定多重继承时的方法解析顺序(MRO)。MRO是指Python在寻找一个类的父类中的方法时,遵循的搜索顺序。

在你的例子中,类E继承了类C和类D,而类C继承了类A,类D继承了类B。根据C3算法,类E的MRO是:

E -> C -> A -> D -> B -> object

这意味着Python会先在类E中寻找say方法,如果没有找到,就会按照上面的顺序依次在父类中寻找。

因此,当你调用e.say()时,Python会先执行类E中的say方法,打印出"FishE",然后调用super().say(),进入类C中的say方法,打印出"FishC",再调用super().say(),进入类A中的say方法,打印出"FishA",再调用super().say(),进入类D中的say方法,打印出"FishD",再调用super().say(),进入类B中的say方法,打印出"FishB"。最后结束。

所以打印的顺序是:

FishE FishC FishA FishD FishB

希望这能帮助你理解Python的多重继承和MRO。

最佳答案

查看完整内容

这是因为Python使用了C3线性化算法来确定多重继承时的方法解析顺序(MRO)。MRO是指Python在寻找一个类的父类中的方法时,遵循的搜索顺序。 在你的例子中,类E继承了类C和类D,而类C继承了类A,类D继承了类B。根据C3算法,类E的MRO是: E -> C -> A -> D -> B -> object 这意味着Python会先在类E中寻找say方法,如果没有找到,就会按照上面的顺序依次在父类中寻找。 因此,当你调用e.say()时,Python会先执行类E中的sa ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-3 21:08:46 | 显示全部楼层    本楼为最佳答案   
这是因为Python使用了C3线性化算法来确定多重继承时的方法解析顺序(MRO)。MRO是指Python在寻找一个类的父类中的方法时,遵循的搜索顺序。

在你的例子中,类E继承了类C和类D,而类C继承了类A,类D继承了类B。根据C3算法,类E的MRO是:

E -> C -> A -> D -> B -> object

这意味着Python会先在类E中寻找say方法,如果没有找到,就会按照上面的顺序依次在父类中寻找。

因此,当你调用e.say()时,Python会先执行类E中的say方法,打印出"FishE",然后调用super().say(),进入类C中的say方法,打印出"FishC",再调用super().say(),进入类A中的say方法,打印出"FishA",再调用super().say(),进入类D中的say方法,打印出"FishD",再调用super().say(),进入类B中的say方法,打印出"FishB"。最后结束。

所以打印的顺序是:

FishE FishC FishA FishD FishB

希望这能帮助你理解Python的多重继承和MRO。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-3 21:09:03 | 显示全部楼层
打印的顺序是 "FishB FishD FishA FishC FishE"。

在这个例子中,我们有五个类:A、B、C、D和E。E是C和D的子类,C是A的子类,D是B的子类。

当我们创建一个E的实例e并调用e.say()时,以下是发生的过程:

1. E类的say方法被调用。
2. 在E类中,super().say()调用了C类的say方法。
3. 在C类中,super().say()调用了A类的say方法。
4. 在A类中,super().say()调用了D类的say方法。
5. 在D类中,super().say()调用了B类的say方法。
6. 在B类中,打印了"FishB"。
7. 回到D类,打印了"FishD"。
8. 回到A类,打印了"FishA"。
9. 回到C类,打印了"FishC"。
10. 回到E类,打印了"FishE"。

这个顺序是由Python的方法解析顺序(Method Resolution Order,MRO)决定的。MRO定义了在多重继承中方法的查找顺序。在这个例子中,MRO的顺序是E -> C -> A -> D -> B。所以,方法的调用顺序就是按照这个顺序来的。

希望这个解释能帮助你理解为什么打印的顺序是这样的。如果你还有其他问题,请随时提问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-3 21:09:05 | 显示全部楼层
通过观察代码的继承关系,可以解释为什么打印的顺序是这样的。让我们逐个类分析:

1. 类A中的say方法调用了super().say(),表示调用该类的父类的同名方法(即类C)。因此,首先执行类C的say方法。

2. 类C的say方法同样调用了super().say(),这次会调用类D的say方法,因为类C的直接父类是类D。

3. 类D的say方法打印了"FishB"。

4. 执行完类D的say方法后,返回到类C的say方法,再打印"FishC"。

5. 回到类A的say方法,打印"FishA"。

6. 最后,回到类E的对象e的say方法,打印"FishE"。

因此,最终打印的顺序是:"FishB" -> "FishC" -> "FishA" -> "FishE"。

这是由于多重继承的特性所决定的。在使用super函数时,它会按照类的继承顺序依次调用父类的方法。在上述代码中,类E继承自类C和类D,而类C又继承自类A,类D继承自类B。因此,当调用super时,会按照从左至右的顺序依次调用各个父类的方法。

希望以上解释能够帮助你理解代码的执行顺序。如果还有其他问题,请随时提问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-3 21:09:11 | 显示全部楼层
问题分析:

在上述代码中,存在多重继承关系。类E继承自类C和类D,类C继承自类A,而类D继承自类B。每个类都有一个名为say的方法,并且在该方法中使用了super().say()来调用父类的同名方法。

执行顺序解释:

当调用e.say()时,会按照方法解析顺序(MRO)来决定方法的执行顺序。方法解析顺序是根据类的继承关系确定的,可以通过E.mro()来查看方法解析顺序。

在上述代码中,E.mro()的结果为:[<class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.D'>, <class '__main__.B'>, <class 'object'>]。可以看到,方法解析顺序是从左到右的深度优先顺序。

具体的执行顺序如下:

1. 当调用e.say()时,会按照方法解析顺序的顺序依次执行每个类的say方法。

2. 首先调用类Esay方法,然后在该方法内部使用super().say()调用类Csay方法。

3. 类Csay方法执行后,又使用super().say()调用了类Asay方法。

4. 到达类Asay方法,该方法内部没有使用super().say()调用其他方法。

5. 然后返回到类Csay方法,打印出"FishA"。

6. 返回到类Esay方法,继续执行,在打印出"FishA"后,打印出"FishC"。

7. 接下来,类Dsay方法被调用,打印出"FishB"。

8. 最后,返回到类Esay方法,打印出"FishD"和"FishE"。

总结:

综上所述,以上代码的打印顺序是 "FishA" -> "FishC" -> "FishB" -> "FishD" -> "FishE"。

希望以上解释能够帮助你理解多重继承下super()函数的执行顺序。如果还有其他问题,请随时提问。

如果回答对你有帮助,请给我一个最佳答案!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-3 21:22:23 | 显示全部楼层
根据给出的代码,打印的顺序如下:

FishB
FishD
FishA
FishC
FishE

解释如下:

创建了类 A 和类 B,它们都有一个名为 say 的方法。
类 C 继承自类 A,并重写了 say 方法。在其重写的方法中,通过 super().say() 调用了父类 A 的 say 方法。
类 D 继承自类 B,并重写了 say 方法。在其重写的方法中,先打印 "FishB",然后通过 super().say() 调用了父类 B 的 say 方法。
类 E 继承自类 C 和类 D,并重写了 say 方法。在其重写的方法中,先通过 super().say() 调用了父类 C 的 say 方法,然后打印 "FishE"。
创建了 E 类的实例 e,并调用 e 的 say 方法。
当调用 e.say() 时,首先会执行类 E 的 say 方法。然后,由于类 E 继承自类 C 和类 D,且在类 E 的 say 方法中调用了 super().say(),因此会按照方法解析顺序依次调用类 C 和类 D 的 say 方法。
类 C 的 say 方法中通过 super().say() 调用了类 A 的 say 方法,因此会先执行类 A 的 say 方法,打印 "FishA"。
最后,类 D 的 say 方法中打印 "FishD",而类 E 的 say 方法中打印 "FishE"。
所以,最终的打印顺序是:FishB -> FishD -> FishA -> FishC -> FishE。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-25 21:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表