多重继承

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

这是一个简单的例子:

class Foo(object):
    foo = 'attr foo of Foo'
    

class Bar(object):
    foo = 'attr foo of Bar' # we won't see this.
    bar = 'attr bar of Bar'

class FooBar(Foo, Bar):
    foobar = 'attr foobar of FooBar'

现在,如果我们实例化 FooBar,如果我们查找 foo 属性,我们会看到首先找到 Foo 的属性

fb = FooBar()

>>> fb.foo
'attr foo of Foo'

这是 FooBar 的 MRO:

>>> FooBar.mro()
[<class '__main__.FooBar'>, <class '__main__.Foo'>, <class '__main__.Bar'>, <type 'object'>]

可以简单地说,Python 的 MRO 算法是

  1. 深度优先(例如 FooBar 然后 Foo)除非
  2. 共享父母(object)被孩子(Bar)和
  3. 不允许循环关系。

也就是说,例如,当 FooBar 继承自 Bar 时,Bar 不能从 FooBar 继承。

有关 Python 的综合示例,请参阅维基百科条目

继承的另一个强大功能是 super。super 可以获取父类功能。

class Foo(object):
    def foo_method(self):
        print "foo Method"

class Bar(object):
    def bar_method(self):
        print "bar Method"

class FooBar(Foo, Bar):
    def foo_method(self):
        super(FooBar, self).foo_method()

使用类的 init 方法进行多重继承,当每个类都有自己的 init 方法然后我们尝试多个 ineritance 然后只有 init 方法被调用的类首先被继承。

对于下面的示例,只有 Foo 类的 init 方法被调用 Bar 类 init 而不被调用

    class Foo(object):
        def __init__(self):
            print "foo init"

    class Bar(object):
        def __init__(self):
            print "bar init"

    class FooBar(Foo, Bar):
        def __init__(self):
            print "foobar init"
            super(FooBar, self).__init__()

    a = FooBar()

输出:

    foobar init
    foo init

但这并不意味着 Bar 类不是继承。最终 FooBar 类的实例也是 Bar 类和 Foo 类的实例。

print isinstance(a,FooBar)
print isinstance(a,Foo)
print isinstance(a,Bar) 

输出:

True
True
True