Eas*_*sun 5 python multiple-inheritance method-resolution-order
假设我定义了四个类如下:
(该代码已经在 Python 3.6.5 上进行了测试。但是,我希望它也可以在 Python 2.7.x 上使用from __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]
Run Code Online (Sandbox Code Playgroud)
注意两点:
class A没有__init__方法;
A根据 mro 信息,C 和 D 具有相同的后继。
所以我想这两个super(C, self).__init__(value)和super(D, self).__init__(value)将触发__init__中定义的方法A。
然而,下面的结果让我很困惑!
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
Run Code Online (Sandbox Code Playgroud)
我们可以看到class D初始化成功,而class C失败。
class C和之间的不同行为是class D什么?
编辑我不认为我的问题是关于 mro(实际上我或多或少知道关于 python 的 mro),我的问题是关于__init___方法的不同行为。
EDIT2我很傻,这是关于先生的。
谢谢你的帮助。
类A没有单独的__init__方法 - 它是通过A`s own查找的mro。
>>> A.__init__ is object.__init__
True
Run Code Online (Sandbox Code Playgroud)B 类有一个单独的__init__方法 - 它不需要遍历mro.
>>> B.__init__ is object.__init__
False
Run Code Online (Sandbox Code Playgroud)请注意,区别在于拥有和继承 __init__。仅仅因为A.__init__可以提供并不意味着A它__init__本身就有一个方法。
当 C 查找其 时super().__init__,会尝试以下操作:
C.__init__ 被跳过A.__init__ 不存在object.__init__ 存在并被称为当 D 查找其 时super().__init__,会尝试以下操作:
D.__init__ 被跳过A.__init__ 不存在B.__init__ 存在并被称为object.__init__ 从不抬头这种差异是使用super而不是显式基类的主要点。它允许将专门的类插入到层次结构中(示例)。
| 归档时间: |
|
| 查看次数: |
4530 次 |
| 最近记录: |