Python - 基类'构造函数被覆盖

时间:2016-12-25 12:58:58

标签: python multiple-inheritance

正如How does Python's super() work with multiple inheritance?中所述,super也可用于多重继承,因为它会在父对象中查找属性。但是什么属性?子类已包含super(如果您查看下面的代码)。如何指定我想要的属性?我想要Error的构造函数。

class Error(object):
    def __init__(self, values):
        self.values = values

class AddDialog(sized_controls.SizedDialog, Error):
    def __init__(self, *args, **kwargs):
        Error.__init__(self, *args)
        super(AddDialog, self).__init__(*args, **kwargs)

1 个答案:

答案 0 :(得分:1)

就像尝试一样简单:

class Error(object):
    def __init__(self, values):
        self.values = values
        print('Error')

class SizedDialog(object):
    def __init__(self, values):
        self.values = values
        print('SizedDialog')

class AddDialog(SizedDialog, Error):
    def __init__(self, *args, **kwargs):
        print('AddDialog')
        Error.__init__(self, *args)
        super(AddDialog, self).__init__(*args, **kwargs)

现在,super()只不过是你可以使用mro()获得的方法解析顺序(MRO):

>>> AddDialog.mro()
[__main__.AddDialog, __main__.SizedDialog, __main__.Error, object]

因此,在您的情况下,您首先明确地调用__init__() Error。然后super()会在此特定情况下找到__init__()的{​​{1}},因为它位于MRO中的SizedDialog之前。

Error

如果您仅使用>>> a = AddDialog(10) AddDialog Error SizedDialog (无法拨打super()的{​​{1}}),则只能获得__init__() Error

__init__()

最后,如果您只调用SizedDialog的{​​{1}},则它是唯一被调用的class AddDialog(SizedDialog, Error): def __init__(self, *args, **kwargs): print('AddDialog') super(AddDialog, self).__init__(*args, **kwargs) >>> a = AddDialog(10) AddDialog SizedDialog

__init__()

所以你的问题:

  

但是什么属性?

有答案:

您致电的人。

如果您使用Error进行硬连接,或让__init__()找到合适的父类,即MRO中的下一个父类,则无关紧要。 唯一的区别是,如果父类没有class AddDialog(SizedDialog, Error): def __init__(self, *args, **kwargs): print('AddDialog') Error.__init__(self, *args) >>> a = AddDialog(10) AddDialog Error Error可能会调用祖父班的super()。 但这是super()的预期行为。