多重繼承

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