LEEFEI571 发表于 2025-2-23 23:16:47

关于类和对象MRO继承顺序出错的困惑

我写了以下代码:

>>> class A:
...   def ping(self):
...         print("A ping~")
      def pong(self):
            print("A pong")
...
>>> class B(A):
...   def ping(self):
...         print("B ping~")
      def pong(self):
            print("B pong")
...
>>> class C(A):
...   def ping(self):
...         print("C ping~")

...
>>> class D(B, C):
...   def pingpong(self):
...         self.ping()
...         self.pong()         
...
>>> d = D()
>>> d.pingpong()

但在执行时报错,提示AttributeError: 'D' object has no attribute 'pong'

我的困惑是实例化对象d所属的类D里面有pong()函数啊,而且D类的父类里面也有pong()函数且项下也有执行语句(打印 B pong),那为何会报错?麻烦大神帮忙指点一下,谢谢!

FishC 发表于 2025-2-23 23:16:57

你遇到的问题是由于方法解析顺序 (MRO, Method Resolution Order) 导致的。在多重继承的情况下,Python 会根据 C3 线性化算法来决定方法的解析顺序。

这里是你代码的一个简化和可能的修复:

>>> class A:
...   def ping(self):
...         print("A ping~")
...   def pong(self):
...         print("A pong")
...
>>> class B(A):
...   def ping(self):
...         print("B ping~")
...   def pong(self):
...         print("B pong")
...
>>> class C(A):
...   def ping(self):
...         print("C ping~")
...
>>> class D(B, C):
...   def pingpong(self):
...         self.ping()
...         self.pong()         
...
>>> d = D()
>>> d.pingpong()

你可能会得到以下输出:

B ping~
A pong

这说明 MRO 的顺序依次为 D -> B -> C -> A。当调用 self.ping() 时,它会先在类 D 中寻找,然后是 B,找到 ping 方法并执行。同样地,调用 self.pong() 时,也会按照同样的顺序寻找,但由于类 B 中有 pong 方法,它调用了 A 类的 pong 方法,这就是为什么输出是 "A pong"。

如果你想要了解详细的 MRO,可以使用:

>>> print(D.__mro__)

它会打印出类 D 的 MRO 顺序,帮助你理解方法解析的过程。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 关于类和对象MRO继承顺序出错的困惑