【问题标题】:Python base class' implicit super() callPython 基类的隐式 super() 调用
【发布时间】:2019-09-17 21:12:45
【问题描述】:

目前我开始修改我的 python 的 OOP 知识。我偶然发现了super() 定义,它表明它为派生类提供了一组来自基类的实例变量和方法。

所以我有这段代码:

class foo:
    bar = 5

    def __init__(self, a):
        self.x = a

    def spam(self):
        print(self.x)


class baz(foo):
    pass

b = baz(5)
b.spam()

并且这个执行没有super()调用,没有错误,并打印出5。

现在,当我向派生类添加 __init__ 方法时,如下所示:

class foo:
    bar = 5

    def __init__(self, a):
        self.x = a

    def spam(self):
        print(self.x)


class baz(foo):
    def __init__(self, a):
        self.b = a


b = baz(5)
b.spam()

脚本给了我一个错误:AttributeError: 'baz' object has no attribute 'x'。

所以这表明,如果我的班级有一个默认的__init__,它也有一个明确的super() 调用。我实际上找不到任何信息来证实这一点,所以我只是想问一下我是否正确。

【问题讨论】:

  • 我不明白你在问什么。如果你没有定义一个方法,那么 Python 会从最近的祖先那里找到定义——这就是继承的全部意义。如果您确实定义了它,那么您可以根据需要调用 super。
  • 所以,当我有一个空的派生类时 - 它是基类 __init__,而不是带有 super() 调用的“生成”派生类 __init__?
  • this 有帮助吗?
  • 据我所知,它没有说明空派生类,我只是好奇它是如何实现的——它是隐式调用基类__init__ 还是创建自己的@987654335 @ 然后调用super()
  • 您缺少方法解析顺序的概念。如果调用了未定义的方法,Python 将通过 MRO 进行处理,直到找到定义。没有代码生成。

标签: python python-3.x class inheritance


【解决方案1】:

问题是当您在子类baz 中定义方法__init__ 时,您不再使用父类foo 中的方法。那么,当你调用b.spam()时,x就不存在了,因为这是在父类的__init__方法中定义的。

如果您想要调用父类的__init__ 方法并添加您自己的逻辑,您可以使用以下方法来解决此问题:

class baz(foo):
    def __init__(self, a):
        super().__init__(10) # you can pass any value you want to assign to x
        self.b = a

>>> b = baz(5)
>>> b.spam()
10

【讨论】:

  • 是的,现在当我读到 Python 中的 MRO 时,我明白了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-22
  • 2011-06-15
  • 2020-04-06
  • 2021-03-17
  • 2018-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多