【问题标题】:Python multi inheritance super__init__(**kwargs) [duplicate]Python多继承super__init__(**kwargs)[重复]
【发布时间】:2021-03-23 22:56:34
【问题描述】:

我是新手,我有这样一个问题,在这段代码中

class One:
    def __init__(self, x, **kwargs):
        super().__init__(**kwargs)
        self.x = x**2


class Two:
    def __init__(self, y, **kwargs):
        super().__init__(**kwargs)
        self.y = y**3


class Three(One, Two):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        print(self.y, self.x)


Three(x=1, y=2)

我了解 **kwargs 是如何工作的,但不明白为什么需要调用父母的 init 函数 第一和第二班。就我而言,在我看到的第一类和第二类的情况下,**kwargs 只是空的 字典。为什么需要我 super().init(**kwargs) ,如果 kwargs 只是空字典

我也尝试了另一种方法,没有 kwargs

class Three(One, Two):
    def __init__(self, x,y):
        One.__init__(self,x)
        Two.__init__(self,y)
        print(self.y, self.x)

这种方式更容易理解,但是谁能解释一下它是如何与 **kwargs 一起工作的。谢谢

【问题讨论】:

  • super 是一个误导性名称。它调用方法解析顺序中的下一个实现,而不是超类的实现。 (“超类”在多重继承中甚至不是一个定义明确的概念。)
  • 尝试打印它,你会发现它并不总是一个空字典。
  • “在我的情况下,我在第一类和第二类中看到 **kwargs 只是空字典。”你为什么这么认为?你测试了吗?
  • @KarlKnechtel 我搜索了[python] super kwargs,它大约是按相关性排序的第 10 个结果。其余的都是相关的,只是不够接近而不能重复。我发现在单独的选项卡中进行搜索要容易得多,而不是使用很难使用的“关闭为重复”对话框中内置的搜索。

标签: python python-3.x


【解决方案1】:

根据您的代码,您可以这样做:

class Three(One, Two):
    pass

除非你在实例化时确实有一些特定的东西要在三中实现

但是,您需要将 **kwargs 保留在您的 2 个父类上,因为它们的 __init__ 将接收传递给 Three.__init__ 的所有未定义关键字参数

建议:使用调试器(如 PyCharm/VSCode)来可视化创建实例时发生的情况,观察代码的运行情况非常好。

super 只是让 Python 决定调用父类方法的顺序(MRO)的一种方式

当 python 执行 Three(x=1, y=2) 时,它实际上发送到 Three.init 3 件事:

  1. self:正在实例化的实例
  2. 位置参数元组(通常称为args
  3. 关键字 args 的字典(通常命名为 kwargs

在您的情况下,由于您只使用关键字参数,args 将是一个空元组,而 kwargs 将是 {'x': 1, 'y': 2}

然后:

  1. One.__init__(x, **kwargs) 将占用 x 并将 y 留在 kwargs 中
  2. Two.__init__(y, **kwargs) 将占用 y 并将 x 留在 kwargs 内

【讨论】:

  • 但是 super().__init__(**kwargs) 做什么?当我在第一类和第二类中 print(kwargs) 时,它只是空字典 {} 那么为什么需要以空字典作为参数调用对象初始函数呢?
  • “但是 super().__init__(**kwargs) 做什么?”您是否尝试将其复制并粘贴到搜索引擎中? “当我在第一类和第二类中打印(kwargs)时,它只是空字典{}”不,不是。在One 中,您得到一个y 键,因为它尚未分配给命名参数。 super 调用允许将该信息传递给Two.__init__super 魔法的设计方式可以让这种情况发生即使One 不知道Two,因为object__init__ed是Three(两者都知道)。
猜你喜欢
  • 2015-05-04
  • 2020-06-15
  • 2018-11-06
  • 1970-01-01
  • 2016-10-16
  • 2022-09-22
  • 2020-12-18
  • 2021-08-05
  • 1970-01-01
相关资源
最近更新 更多