【问题标题】:Inheriting form two classes in python with super. can you call parent init methods with super()? [duplicate]用super继承python中的两个类。你能用 super() 调用父初始化方法吗? [复制]
【发布时间】:2021-06-30 00:44:04
【问题描述】:

假设:

class Father():
    def __init__(self,fathername):
        self.papa = f"The father is {fathername.upper()}"

class Mother():
    # Mother class is COMPLETELY DIFFERENT AS Father.
    # The important thing is that they both built an attribute each.
    def __init__(self,mothername):
        self.mama = f"the mother is {mothername.lower()}"
        
class Child3(Father,Mother):
    def __init__(self,name,fathername,mothername):
        Father.__init__(self,fathername)
        Mother.__init__(self,mothername)
        self.name=name

以下两项均有效:

c = Child3('Noa',fathername='J',mothername='M')
c = Child3('Noa','J','M')

到目前为止一切顺利。 但是假设我想从几个类继承(不是多个嵌套继承,而是一个类从几个不继承其他任何东西的类继承) 如何使用 super() 来初始化父类?

以下不起作用:

class Child4(Father,Mother):
    def __init__(self,name,fathername,mothername):
        super().__init__(self,fathername=fathername,mothername=mothername)
        self.name=name

TypeError: init() 为参数 'fathername' 获得了多个值

之前的一些咨询:

  1. How does Python's super() work with multiple inheritance? 这是一个非常完整的非常好的答案,我前段时间已经投票了。然而,这个问题有点不同,并不完全是我在这里问的情况,即 MRO(方法解析顺序)在这里并不重要。我想实现一种硬编码初始化父类以访问所有属性的方法。在提到的问题中,得票最多的答案在父类中没有属性。在投票第二多的答案中,父类也没有属性。然而,在另一个答案中,对具有多继承的 MRO 进行了非常完整的解释,这又不是重点,因为只有一个继承级别。

  2. 在另一个获得很多赞成票的问题中,也没有父类的属性:Calling parent class __init__ with multiple inheritance, what's the right way?

  3. 这是更接近的一个,但没有使用 super() Python - Calling __init__ for multiple parent classes 实现解决方案 实际上建议远离继承范式

  4. 这是一个接近的:calling init for multiple parent classes with super?,但我看到父类中有 super(),这会适得其反,因为目标不必修改父类。

为了理解这个例子的用途以及为什么我必须使用继承,认为第一个父类调用一个 API 并执行几个 1000 秒的代码 NLP 过程来提取 API 响应的数据。第二个父类也是如此。然后子类将尝试使用 NLP 进一步比较两者来获得见解。

Mother 和 Father 的课程。它们不是我编码的。我没有机会修改它们。它们不依赖于任何其他类。

【问题讨论】:

  • 我支持重新考虑多重继承是否是最佳解决方案的建议。继承多个接口是可以的,但通过继承“购买”功能通常是一个糟糕的设计。
  • 考虑this 回答。
  • 感谢@dawg。这确实是一个很好的问题/答案。尽管如此,出于某种原因,所有这些示例都不要使用属性变量。即在我的情况下,我在实例化子类时需要做的第一件事就是调用父类和母类的属性。它不仅仅是调用父类的方法。是关于在Child中使用父类的属性。
  • 你已经有了选择:你的父类正确地合作(你不能这样做,因为你不拥有它们);你明确地调用它们(这不会扩展);或者你做的不是继承。您可能不喜欢这些选项,但我们对此无能为力。
  • “大喊大叫”对任何人都没有帮助;我们需要更多上下文来说明为什么这些答案不能解决您的具体问题,因为您当前的解释没有意义。从最后一段中,我什至不确定为什么您认为继承是要走的路,看来您应该在这些“父”类的 list 上进行组合。

标签: python multiple-inheritance super


【解决方案1】:

一个孩子有一个母亲和父亲,最好将其设计为包含母亲和父亲的属性。我认为以下类定义对您的情况更有意义:

class Person():
    def __init__(self, name):
        self._name = name

    def get_name(self):
        return self._name

class Child(Person):
    def __init__(self, name, father_name, mother_name):
        super().__init__(name)
        self._father = Person(father_name)
        self._mother = Person(mother_name)

    def get_father_name(self):
        return self._father.get_name()

    def get_mother_name(self):
        return self._mother.get_name()


child = Child('Peter', 'Joseph', 'Mary')
print(child.get_name(), child.get_father_name(), child.get_mother_name())

打印:

Peter Joseph Mary

【讨论】:

  • 感谢您的回答@Booboo。不幸的是,这不会飞。想象这样一种情况,其中母亲和父亲类完全相互独立,由两个不同的人编码。 Child 类应进一步将结果与其他 NLP 方法结合,以进一步获得其他结果。我没有可能修改这两个父类。
  • 我会同意考虑到你的前提。但我的前提是,编写原始MotherFather 类的人犯了严重错误;这是我唯一的观点。我不认为你会在一个真正的职业 IT 部门找到你的实际情况。无论如何,我希望不会。这些是设计不佳的类,不能用于多重继承,其抽象相当无用。
  • 但我的主要观点是,即使你坚持使用 original 类定义,也不应该使用多重继承。相反,您应该使用遏制。
  • @Booboo 我认为您从字面上阅读类名。我认为它们只是作为一个例子,所以这个建议并不是很有帮助。如果你想从字面上理解,我可以批评你提出的设计,指出事实上并不是每个孩子都有一个母亲和一个父亲。有单亲父母、同性父母和非二元父母,有些孩子没有父母。但这显然忽略了问题的重点,即关于多重继承,而不是软件设计。
  • 感谢@Booboo 的见解。事实上,正如我现在编辑的问题,父亲和母亲类完全不同,它们绝不可能是单个类的两个实例。 Booboo:我们不是在谈论 IT 部门,而是要找到一种方法来重用实际上没有 CS 学位的其他人完成的代码,并使用 python 作为辅助工具。我也有这样的经验,当阅读多继承时,SO 中的人们通常会很快跳到复杂继承链中的 MRO,但我很少看到简单的解决方案。不过我还是会看看“作曲”
猜你喜欢
  • 2016-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 2016-06-24
  • 2019-04-07
相关资源
最近更新 更多