学习Python中的多重继承

160 阅读2分钟

Python 具有利用多重继承的能力,它允许一个子类从多个父类继承功能。很多时候,多重继承是相当棘手的,一些编程语言如Java严格禁止它。有些时候,多重继承也有其用途。它可以被用来创建具有两套不同行为的对象。Python 使用了一种叫做方法解析顺序 (Method Resolution Order) 的东西来决定如何从一个以上的超类继承。我们现在来看看它是如何工作的。


多重继承的例子

在下面的代码中,首先我们看到有两个类,类一和类二,每个类都定义了一个属性。在类一中,我们有 **color**而在类二中,我们有 sound.然后是第三个名为Class Three的类,它把Class One和Class Two都列为基类,用逗号隔开,这就是你如何同时从多个类中继承。在类三中,有一个方法可以打印出这些属性。该 **showprops()**方法打印出 **self.color**并且还打印出了 self.sound,每一个都是从不同的类中继承的(多重继承)。

class One():
    def __init__(self):
        super().__init__()
        self.color = 'One color'
        self.name = 'Set In Class One'

    def karate_chop(self):
        print('Whack!')


class Two():
    def __init__(self):
        super().__init__()
        self.sound = 'Two sound'
        self.name = 'Set In Class Two'

    def karate_chop(self):
        print('Super Whack!!')


class Three(Two, One):
    def __init__(self):
        super().__init__()

    def showprops(self):
        print(self.color)
        print(self.sound)
        print(self.name)

实例化一个对象

obj_three = Three()

这里我们实例化了Three()类,并将其赋值给obj_three变量。Three()同时继承了One和Two类。但是请注意,由于我们以相反的方式传入继承的类,即Three(Two, One),它影响到最终对象如何查找属性和方法。我们可以通过查看方法的解析顺序来了解这一点。


MRO

Python 使用 C3 线性化算法来决定解析类属性的顺序,包括方法。这就是所谓的方法解析顺序(MRO)。

print(Three.__mro__)
(<class '__main__.Three'>, <class '__main__.Two'>, <class '__main__.One'>, <class 'object'>)

这告诉我们,类三具有最高的优先权,类二是第二,类一是第三。当我们运行下面的代码时,请牢记这一点。

obj_three.showprops()
One color
Two sound
Set In Class Two
obj_three.karate_chop()
Super Whack!!

类的顺序

如果我们改变第三类的定义,我们的代码输出会有什么变化呢?

class Three(One, Two):
    def __init__(self):
        super().__init__()

    def showprops(self):
        print(self.color)
        print(self.sound)
        print(self.name)
print(Three.__mro__)
(<class '__main__.Three'>, <class '__main__.One'>, <class '__main__.Two'>, <class 'object'>)

obj_three.showprops()

One color
Two sound
Set In Class One
obj_three.karate_chop()
Whack!

类一和类二都有一个名字属性和一个karate_chop()方法。该属性的值和该方法的输出是不同的,这是基于超类被传递到子类中的方法解析顺序。当试图在 Python 中实现多重继承时,这是一个需要注意的重要概念。