多重继承并将参数传递给 python 中继承的 class

Multiple inheritance and passing arguments to inherited class in python

我定义了以下 classes:

class A(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
        self.c = ""

    def mA1(self):
        print "Method 1 in A"

    def mA2(self):
        print "Method 2 in A"

    def mA3(self):
        print "Method 3 in A"

class B(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
        self.x = 0

    def mB1(self):
        print "Method 1 in B"

class C(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
        self.c = ""
        self.y = 1

    def mC1(self):
        print "Method 1 in C"

    def mC2(self):
        print "Method 2 in C"

可以看出,它们在构造函数中采用相同的输入参数。现在,我想创建一个继承自所有 ABC 的 class D,以便我可以直接将参数传递给 D的构造函数如下:

clsT = D(1, 2)

所以,我尝试了以下修改后的定义:

class A(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
        self.c = ""

    def mA1(self):
        print "Method 1 in A"

    def mA2(self):
        print "Method 2 in A"

    def mA3(self):
        print "Method 3 in A"


class B(A):
    def __init__(self, **kw):
        super(B, self).__init__(**kw)
        self.x = 0

    def mB1(self):
        print "Method 1 in B"


class C(A):
    def __init__(self, **kw):
        super(C, self).__init__(**kw)
        self.c = ""
        self.y = 1

    def mC1(self):
        print "Method 1 in C"

    def mC2(self):
        print "Method 2 in C"


class D(A, B, C):
    def __init__(self, a, b):
        super(D, self).__init__(a=a, b=b)


ci = D(1, 2)

print "a = ", ci.a
print "b = ", ci.b
print "c = ", ci.c
print "x = ", ci.x
print "y = ", ci.y

上面的方法似乎不起作用,并出现以下错误:

    class D(A, B, C):
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases B, C, A

可能出了什么问题?难道真的要求BC必须包含super(),在中层基础classes上创建线性继承吗?我的解释有其他选择吗?如果没有,如何调整我的使其工作?

我如下更改了 D 的 class 定义并且有效

class D(B, C, A):
    def __init__(self, a, b):
        super(D, self).__init__(a=a, b=b)

所以整体 class 看起来像,(我删除了方法以保持代码简短)

class A(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b
        self.c = ""

class B(A):
    def __init__(self, **kw):
        super(B, self).__init__(**kw)
        self.x = 0

class C(A):
    def __init__(self, **kw):
        super(C, self).__init__(**kw)
        self.c = ""
        self.y = 1


class D(B, C, A):
    def __init__(self, a, b):
        super(D, self).__init__(a=a, b=b)


c = D(1, 2)
print(c.a, c.b, c.x, c.c, c.y)

输出将是

1 2 0  1

这是由于MRO algorithm which says (More details in this 这里的一条规则,但要点是

a class always appears before its ancestor ("monotonicity")

因此B和C需要出现在A之前,因为A是B和C的祖先

或者换句话说: D 继承自 A、B 和 C。因为 B 和 C 已经继承自 A,所以 python 现在无法确定首先查找什么方法 class; A 或 B 和 C,如果您使用旧的定义顺序。 D(A, B, C)