与 super() 和 __init__() 相关的问题 [英] Question related to super() with __init__()

查看:31
本文介绍了与 super() 和 __init__() 相关的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下 3 个类,

class A(object):
    def __init__(self):
        print('A')
    def test(self):
        print('1')

class B(A):
    def __init__(self):
        super(B,self)        ## if .__init__() is not given here
        print('B')

class C(B, A):
    def __init__(self):
        super(C, self).__init__()
        print('C')

如果我运行D = C(),它会返回

B
C

如果我运行 print(C.__mro__),它将给出 (, , , ).我认为这意味着 A 类将在 mro 列表中执行.然而,情况并非如此.

If I run print(C.__mro__), it will gives (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>). I think that means class A will be executed as it is inside the mro list.However, this is not the case.

我想问一下为什么 .__init__() 对于 A.__init__() 发生是必要的.

I want ask why .__init__() is necessary for A.__init__() happening.

推荐答案

不是是什么意思!

我认为您实际上对两件事感到困惑:mro 是什么,以及 Python 中子类构造函数的性质.我们先来看看mro.

I think you are actually confused about two things: what mro is, and the nature of subclass constructors in Python. Let's look at mro first.

mro 表示方法解析顺序",并指定 Python 解释器查找适当命名的方法的顺序.

mro means "method resolution order", and specifies the order in which the Python interpreter will look for appropriately named methods.

因此,假设您有以下类层次结构:

So, say you have the following class hierarchy:

class A:

    def deepest(self):
        print('I wonder where this is coming from...')

    def deeer(self):
        print('deeper from A')

    def deep(self):
        print('deep from A')

class B(A):

    def deeper(self):
        print('deeper from B')

    def deep(self):
        print('deep from B')

class C(B):

    def deep(self):
        print('deep from C')

c = C()
c.deep()
c.deeper()
c.deepest()
print(c.__mro__)

输出:

deep from C
deeper from B
I wonder where this is coming from...
(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

当我们调用 deep 时,Python 在 C 中寻找它,因为 Cmro 中是第一个.它找到了它,不再继续.

When we call deep, Python looks for it in C, since C is first in the mro. It finds it and goes no further.

另一方面,对于deeper,Python在C中找不到它,因此会转到层次结构中的下一个,即B,并找到它.

On the other hand, for deeper, Python cannot find it in C and therefore goes to the next one in the hierarchy, which is B, and finds it.

deepest 也一样,只在 A 中找到.

Same thing for deepest, which is only found in A.

现在,让我们将其连接到 __init__.

Now, let's connect this to __init__.

在这种情况下,当您从 super 调用 __init__ 时,Python 会查找层次结构中的第一个超类,即 B,然后调用它的 __init__ 方法.

In this case, when you call __init__ from super, Python looks for the first superclass in the hierarchy, which is B, and calls its __init__ method.

但是,如果 B__init__ 方法没有调用 A.__init__,则链就停在那里!

However, if the __init__ method of B does not call A.__init__, then the chain stops there!

与其他语言不同,子类不会自动调用其超类的__init__方法,除非他们当然没有定义自己的__init__方法,那么就是一个casec.deeper(),同上.

Unlike other languages, subclasses do not automatically call the __init__ method of their superclasses, unless of course they have not defined their own __init__ methods, then it is a case of c.deeper(), as above.

这符合 Python 的哲学我们都同意这里的成年人"——如果你不想调用超类的 __init__,那么当然可以,但你要承受后果.

This is in line with Python's philosophy of "we're all consenting adults here" - if you don't want to call the superclass's __init__, then sure, do it, but you bear the consequences.

这篇关于与 super() 和 __init__() 相关的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆