如果没有__init__方法定义一个类会怎么样?

假设我已经定义了以下四个类:

(代码已经在Python 3.6.5上进行了测试.但是,我预计它也适用于Python 2.7.x,带有__future__ import print_function)

In [1]: class A(object):
   ...:     pass
   ...: 
   ...: class B(object):
   ...:     def __init__(self, value):
   ...:         print('B(value=%s)' % value)
   ...: 
   ...: class C(A):
   ...:     def __init__(self, value):
   ...:         print('C(value=%s)' % value)
   ...:         super(C, self).__init__(value)
   ...: 
   ...: class D(A, B):
   ...:     def __init__(self, value):
   ...:         print('D(value=%s)' % value)
   ...:         super(D, self).__init__(value)
   ...:         

In [2]: C.mro()
Out[2]: [__main__.C, __main__.A, object]

In [3]: D.mro()
Out[3]: [__main__.D, __main__.A, __main__.B, object]

注意两件事:

>没有__init__方法的A类;
>根据mro,C和D都有相同的后继A.
信息.

所以我认为super(C,self).__ init __(value)和super(D,self).__ init __(value)都会触发A中定义的__init__方法.

但是,以下结果让我非常困惑!

In [4]: C(0)
C(value=0)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-75d9b7f7d447> in <module>()
----> 1 C(0)

<ipython-input-1-5252938615c6> in __init__(self, value)
      9     def __init__(self, value):
     10         print('C(value=%s)' % value)
---> 11         super(C, self).__init__(value)
     12 
     13 class D(A, B):

TypeError: object.__init__() takes no parameters

In [5]: D(1)
D(value=1)
B(value=1)
Out[5]: <__main__.D at 0x2a6e8755b70

我们可以看到D类初始化成功,而C类失败.

C类和D类之间的不同行为是什么?

编辑我不认为我的问题是关于mro(实际上我或多或少知道关于python的mro),我的问题是关于__init___方法的不同行为.

EDIT2我很傻,这是关于mro的.

谢谢你的帮助.

最佳答案 > A类没有单独的__init__方法 – 它是通过A自己的mro查找的.

>>> A.__init__ is object.__init__
True

> B类有一个单独的__init__方法 – 它不需要遍历mro.

>>> B.__init__ is object.__init__
False

请注意,区别在于继承__init__.仅仅因为可以提供A .__ init__并不意味着A本身具有__init__方法.

>当C查找__init__时,尝试以下操作:

> C .__ init__不存在
> A .__ init__不存在
> object .__ init__存在并被调用

>当D查找__init__时,尝试以下操作:

> D .__ init__不存在
> A .__ init__不存在
> B .__ init__存在并被调用
> object .__ init__从不抬头

这种差异是使用super而不是显式基类的重点.它允许将专用类插入层次结构(example).

    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞