python - 多重继承: only 1 parent init'd

标签 python python-2.7 initialization multiple-inheritance

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

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()。如果我切换继承参数的顺序,则只会初始化无论怎样的第一个类:

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

如何通过一次调用初始化 parent 双方?这不应该是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没有初始化?

最佳答案

Base.__init__BaseWArgs.__init__ 都没有实现对 super().__init__ 的调用,所以显然只有第一个rmo 将被调用。您必须让所有初始化程序遵守协议(protocol)才能正常工作。

此外,由于 Base 在 mro 中排在第一位并且不接受任何参数,这仍然会失败。 “协作” super 调用要求您的方法签名兼容。下面的代码确实按预期委托(delegate)了调用:

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

编辑:关于您的具体用例,似乎 defaultdict 本身并不执行 super 调用,因此除非它是基类中的最后一个,否则调用链将停在那里(嗯,它停在那里,但如果它是最后一个,那不是问题)。

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

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

class Sub(Base):
    def __init__(self):
        print "Sub.__init__():"
        super(Sub, self).__init__()
        self.foo = "bar"


class MyClass(defaultdict, Sub):
    def __init__(self):
        defaultdict.__init__(self, int)
        Sub.__init__(self)

关于python - 多重继承: only 1 parent init'd,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20047989/

相关文章:

python - 为什么 `-(num)**(even_number)` 结果是 `-(num^(even_number))`?

python - 如何根据条件表达式删除一定数量的行?

python - 没有名为 Flask (GAE) 的模块

python 2.7 : delete item from list by value

python - pyqt4从其他py文件绘制圆弧

c++ - 变量不断在循环内重新初始化?

javascript - init 是 Javascript 对象文字的特殊保留关键字吗?

python - 将 OCamCalib 工具箱 Matlab 脚本转换为 Python

python - Google Colaboratory - 超出最大调用堆栈大小

c - 使用 clang 与 gcc 进行 union 零初始化