【问题标题】:Multiple inheritance and passing arguments to inherited class in python多重继承并将参数传递给python中的继承类
【发布时间】:2019-09-25 19:28:00
【问题描述】:

我定义了以下类:

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"

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

clsT = D(1, 2)

所以,我尝试了here 中提到的以下修改后的定义:

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(),在中级基类中创建线性继承?我的解释有其他选择吗?如果没有,如何调整我的使其工作?

【问题讨论】:

    标签: python python-2.7 class inheritance multiple-inheritance


    【解决方案1】:

    我更改了D 的类定义如下,它起作用了

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

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

    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 算法中的一条规则说(更多细节在这个answer 这里,但要点是

    一个类总是出现在它的祖先之前(“单调性”)

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

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

    【讨论】:

    • 太棒了!那么,错误实际上总是指向实际顺序?
    • 是的,错误说明了一切,无法创建consistent 方法解析,一致性问题是因为我在回答@skrowten_hermit 中指出的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 2016-04-25
    • 1970-01-01
    • 2013-05-08
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多