什么是Pythonic实施“钻石继承”的方式?

时间:2015-08-18 14:46:23

标签: python oop inheritance

我正面临一个近乎教科书的钻石继承问题。下面的(相当人工!)示例捕获了它的所有基本特征:

# 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_0middle_1都是类top的子类,其中middle_0会覆盖方法foomiddle_1覆盖方法__init__。基本上,经典的钻石继承设置。对基本模式的一个阐述是middle_1.__init__实际上调用了父类的__init__。 (下面的演示显示了这些类的实际应用。)

我想定义一个类bottom来自foo的“获取” 1 middle_0和来自__init__的{​​{1}}。

实现这样的middle_1类的“pythonic方式”是什么?

演示:

bottom

1 我写“gets”而不是“inherits”,因为我怀疑使用标准的Python继承无法轻易解决这个问题。

2 个答案:

答案 0 :(得分:4)

bottom只是从两者继承而来;你的课程没有任何具体内容可以使这个案例变得特别:

class bottom(middle_0, middle_1):
    pass

演示:

>>> class bottom(middle_0, middle_1):
...     pass
... 
>>> bottom(3, 3).foo()
15

这可以正常工作,因为Python会安排middle_0middle_1top之前搜索方法:

>>> 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