【问题标题】:Multiple inheritance problem with super()super() 的多重继承问题
【发布时间】:2020-07-24 19:20:54
【问题描述】:

我遇到了一个我似乎无法弄清楚的多重继承问题。这是一个非常抽象的最小示例,它重现了我的错误(我的代码比这复杂得多)。

class Thing(object):
    def __init__(self, x=None):
        self.x = x

class Mixin(object):
    def __init__(self):
        self.numbers = [1,2,3]

    def children(self):
        return [super().__init__(x=num) for num in self.numbers]

class CompositeThing(Mixin, Thing):
    def __init__(self):
        super().__init__()

    def test(self):
        for child in self.children():
            print(child.x)

obj = CompositeThing()
obj.test()

根据this,我希望children() 方法返回从self.numbers 构建的Things 列表。相反,我得到TypeError: super(type, obj): obj must be an instance or subtype of type。顺便说一句,如果我不调用构造函数并允许孩子返回super() 3 次(即未实例化的超类),也会发生同样的事情。任何想法为什么会发生这种情况?

提前致谢!

【问题讨论】:

    标签: python-3.x multiple-inheritance mixins super


    【解决方案1】:

    在代码的第 9 行中,您似乎正在尝试调用 __init__object。我假设您打算让 Mixin 继承自 Thing

    class Thing(object):
        def __init__(self, x=None):
            self.x = x
    
    class Mixin(Thing):
        def __init__(self):
            self.numbers = [1,2,3]
    
        def children(self):
            return [super().__init__(x=num) for num in self.numbers] # Now calls Thing.__init__ instead of object.__init__
    
    class CompositeThing(Mixin, Thing):
        def __init__(self):
            super().__init__()
    
        def test(self):
            for child in self.children():
                print(child.x)
    
    obj = CompositeThing()
    obj.test()
    

    【讨论】:

    • 这是不正确的。实际上,Things 有很多种不同的类型,因此 Mixin 需要独立并能够实例化任何 Thing 是什么。我对 MRO 的理解是这是可能的 - 还是我的理解不正确?
    • 可以,但不能使用super()。鉴于Mixin 直接继承自object,运行super() 将返回object 而不是Thing。您可以使用Thing.__init__ 而不是super().__init__ 直接访问Thing。也许更好的解决方案是创建另一个 Mixin 继承自的对象。
    • 问题是直到最后一个孩子(即继承树的叶子)之前,我都不知道我的Mixin 类需要什么样的Thing
    • 另外,这并不能解释为什么将 super() 放在 children() 的定义中会失败并返回 TypeError: super(type, obj): obj must be an instance or subtype of type,而不是简单地返回对 object 类的 3 个引用
    【解决方案2】:

    实际上,我想通了。有两个问题:(1)super() doesn't work as expected inside comprehensions 因为 Py3 中的理解有自己的范围 - 这导致了我遇到的TypeError。 (2) 我真正想要做的是create a new instance of the parent,而不是从父级调用方法。为了清楚起见,我针对后一个问题发布了一个新问题。

    【讨论】:

      猜你喜欢
      • 2020-07-05
      • 1970-01-01
      • 2016-02-25
      • 2020-10-03
      • 2017-07-30
      • 2014-07-01
      • 2020-10-21
      • 1970-01-01
      相关资源
      最近更新 更多