多重繼承
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 演算法是
- 深度優先(例如
FooBar
然後Foo
)除非 - 共享父母(
object
)被孩子(Bar
)和 - 不允許迴圈關係。
也就是說,例如,當 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