python 初始化新属性时,为什么需要调用父类的__init__方法?

ax6ht2ek  于 2023-02-07  发布在  Python
关注(0)|答案(1)|浏览(233)

我是个新程序员,我只是想知道为什么我需要调用子类中父类的__init__方法,如果我没有触及第一个__init__方法中的任何参数,方法解析顺序的要点不就是,如果某个方法不在子类中,父类将在子类之后被调用吗?
fx。如果我有一个类的示例,带有名和姓参数。但是在子类中我添加了一个email,并决定只为email编写一个__init__方法,然后打印名。Python不应该在检查子类后检查父类,看看“名”属性是否在__init__方法中吗?而不是给我一个AttributeError

qni6mghb

qni6mghb1#

方法解析运算符仅与属性 lookup 相关。

class Person:
    def __init__(self, *, first, last, **kwargs):
        super().__init__(**kwargs)
        self.first = first
        self.last = last

class PersonWithEmail:
    def __init__(self, *, email, **kwargs):
        super().__init__(**kwargs)
        self.email = email

p = Person(first="John", last="Doe", email="jdoe@example.com")

当我们调用Person时,我们到达了需要调用Person.__init__的点。因为Person.__init__是定义的,所以我们调用它,并且一旦它返回,我们就完成了。只有当Person.__init__ * 没有 * 定义时,MRO才开始起作用,以找到Person的祖先,该祖先 * 定义了我们可以使用的__init__方法。
Person.__init__中,我们只调用找到的代码。没有对任何继承的__init__方法进行隐式调用。super().__init__在MRO中找到 next 类并调用它,其中定义了__init__方法。只有当MRO中的所有类都在重写方法中使用super时,我们才 * 合作地 * 确保每个适当的方法最终被调用。
如果PersonWithEmail不调用super().__init__,那么firstlast属性就永远不会被定义,示例的初始化仍然不正确。至于不自动调用父示例__init__的决定是否正确,这是您可以争论的问题。我指出,这样做会使__init__在某种程度上变得特别,否则它就不会特别。它是一个和其他方法一样的方法,如果你真的想的话,你可以选择完全覆盖父类的__init__。另外,Python的类系统从早期起已经有了一些发展,而且您在当时可能已经做过的事情现在也不想做,但是更改关于不隐式父调用的规则将是一个破坏兼容性的更改,从来没有被认为是必要的。

相关问题