多重继承:只有一个父初始化

2024-04-26 05:01:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我不明白为什么在下面的代码中只有一个父构造函数被初始化:

class Base(object):
    def __init__(self):
        print "Base::Base():"


class BaseWArgs(object):
    def __init__(self, arg):
        print "BaseWArgs::BaseWArgs(%s):" % arg


class Composite(Base, BaseWArgs):
    def __init__(self):
        super(Composite,self).__init__()

在这种情况下,只调用Base.init()。如果我切换继承参数的顺序,则只初始化第一个类中的任何一个:

^{2}$

如何用一个调用初始化双亲?这难道不是super()的责任吗?在

编辑 我认为我的用例是多重继承的一个特例。我想创建一个使用defaultdict作为基类型的项,但是从第三个类型继承一些附加功能。在

from collections import defaultdict

class Base(object):
    def __init__(self):
        print "Base::Base():"
        super(Base,self).__init__()
        self.val = 'hello world'

class Item(defaultdict, Base):
    def __init__(self):
        super(Item,self).__init__(int)

>>> Item()
defaultdict(<type 'int'>, {})

>>> Item().val
Traceback (most recent call last):
  File "<pyshell#77>", line 1, in <module>
    Item().val
AttributeError: 'Item' object has no attribute 'val'

Base::Base()在哪里迷路?为什么Base没有初始化?在


Tags: self类型baseobjectinitdefargval
1条回答
网友
1楼 · 发布于 2024-04-26 05:01:31

Base.__init__和{}都没有实现对super().__init__的调用,因此显然只有rmo中的第一个被调用。你必须让所有的初始值设定项都遵守协议才能工作。在

此外,由于Base在mro中处于第一位,并且不进行任何论证,这仍将失败。”协作的“超级调用”要求您的方法签名是兼容的。以下代码确实按预期委派调用:

class Base(object):
    def __init__(self):
        print "Base::Base():"
        super(Base, self).__init__()

class BaseWArgs(object):
    def __init__(self, arg):
        print "BaseWArgs::BaseWArgs(%s):" % arg
        super(BaseWArgs, self).__init__()


class Composite(BaseWArgs, Base):
    def __init__(self):
        super(Composite,self).__init__("foo")

c = Composite()

edit:wrt/您的具体用例中,defaultdict似乎不执行super调用本身,因此除非它是基类中的最后一个,否则调用链将停止在那里(好吧,它将停止在那里,但如果它最后出现,这就不是问题)。在

因此,您可以选择使您自己的Base层次结构的初始值设定项与defaultdict的一个兼容,并将defaultdict作为最后一个基类,或者显式地调用defaultdict的初始值设定项,然后Base初始值设定项,即:

^{pr2}$

相关问题 更多 >