我正面临一个近乎教科书的钻石继承问题。下面的(相当人工!)示例捕获了它的所有基本特征:
# CAVEAT: error-checking omitted for simplicity
class top(object):
def __init__(self, matrix):
self.matrix = matrix # matrix must be non-empty and rectangular!
def foo(self):
'''Sum all matrix entries.'''
return sum([sum(row) for row in self.matrix])
class middle_0(top):
def foo(self):
'''Sum all matrix entries along (wrap-around) diagonal.'''
matrix = self.matrix
n = len(matrix[0])
return sum([row[i % n] for i, row in enumerate(matrix)])
class middle_1(top):
def __init__(self, m, n):
data = range(m * n)
matrix = [[1 + data[i * n + j] for j in range(n)] for i in range(m)]
super(middle_1, self).__init__(matrix)
总之,类middle_0
和middle_1
都是类top
的子类,其中middle_0
会覆盖方法foo
和middle_1
覆盖方法__init__
。基本上,经典的钻石继承设置。对基本模式的一个阐述是middle_1.__init__
实际上调用了父类的__init__
。 (下面的演示显示了这些类的实际应用。)
我想定义一个类bottom
来自foo
的“获取” 1 middle_0
和来自__init__
的{{1}}。
实现这样的middle_1
类的“pythonic方式”是什么?
演示:
bottom
1 我写“gets”而不是“inherits”,因为我怀疑使用标准的Python继承无法轻易解决这个问题。
答案 0 :(得分:4)
bottom
只是从两者继承而来;你的课程没有任何具体内容可以使这个案例变得特别:
class bottom(middle_0, middle_1):
pass
演示:
>>> class bottom(middle_0, middle_1):
... pass
...
>>> bottom(3, 3).foo()
15
这可以正常工作,因为Python会安排middle_0
和middle_1
在top
之前搜索方法:
>>> bottom.__mro__
(<class '__main__.bottom'>, <class '__main__.middle_0'>, <class '__main__.middle_1'>, <class '__main__.top'>, <type 'object'>)
这显示了该类的方法解析顺序;它是用于查找方法的顺序。因此,在bottom.__init__
上找到了middle_1
,在bottom.foo
上找到了middle_0
,因为它们都列在top
之前。
答案 1 :(得分:2)
我认为
一个类底部,从mid_0“获取”1 foo,从middle_1“获取”__init__。
将由
完成open