<p><code>super()</code>是一个<em>代理</em>对象,它使用<strong><em>方法解析顺序(MRO)</em></strong>来确定在对<code>super()</code>执行调用时要调用的方法。你知道吗</p>
<p>如果我们检查<code>ClassFour</code>的<code>__mro__</code>,我们得到:</p>
<pre><code>>>> ClsFour.__mro__
(<class '__main__.ClsFour'>, <class '__main__.ClsThree'>, <class '__main__.ClsThreee'>, <class '__main__.ClsTwo'>, <class '__main__.ClsOne'>, <type 'object'>)
</code></pre>
<p>或者我自己把它缩短了(不是Python输出):</p>
<pre><code>>>> ClsFour.__mro__
(ClsFour, ClsThree, ClsThreee, ClsTwo, ClsOne, object)
</code></pre>
<p>现在<code>super(T,self)</code>是一个代理对象,它使用来自(但不包括)<code>T</code>的MRO。这意味着<code>super(ClsFour,self)</code>是一个代理对象,它可以处理:</p>
<pre><code>(ClsThree, ClsThreee, ClsTwo, ClsOne, object) # super(ClsFour,self)
</code></pre>
<p>如果查询一个类的属性(方法也是属性),那么Python将遍历MRO并检查元素是否具有这样的属性。因此它将首先检查<code>ClsThree</code>是否有<code>__init__</code>属性,如果没有,它将继续在<code>ClsThreee</code>中查找它,依此类推。从它找到这样的属性的那一刻起,它将停止并返回它。你知道吗</p>
<p>因此<code>super(ClsFour,self).__init__</code>将<strong>返回<code>ClsThree.__init__</code>方法</strong>。MRO还用于查找未在类级别定义的方法、属性等。因此,如果您使用<code>self.x</code>,<code>x</code>不是对象的属性,也不是<code>ClsFour</code>对象的属性,它将再次遍历MRO以搜索<code>x</code>。你知道吗</p>
<p>如果要调用<em>all</em>的<code>__init__</code>调用<code>ClassFour</code>的<em>直接</em>父级,可以使用:</p>
<pre><code>class ClsFour(ClsThree, ClsThreee):
def __init__(self):
# call *all* *direct* parents __init__
for par in ClsFour.__bases__:
par.__init__(self)
</code></pre>
<p>这可能是最优雅的,因为如果基地改变,它仍然会工作。注意,您必须确保每个父级都存在<code>__init__</code>。但是,由于它是在<code>object</code>级别定义的,因此我们可以放心地假设这一点。然而,对于其他属性,我们不能做出这样的假设。你知道吗</p>
<p><strong>编辑</strong>:因此<code>super()</code>并不</strong>必要地指向该阶级的父母、祖父母和/或祖先。但是对于<em>对象</em>的父类。你知道吗</p>
<p><code>ClsThree</code>类中的<code>super(ClsThree,self)</code>将-假设它是一个<code>ClsFour</code>对象,使用相同的mro</strong>(因为它从<code>self</code>获取<code>mro</code>)。因此<code>super(ClsThree,self)</code>将检查以下类序列:</p>
<pre><code>(ClsThreee, ClsTwo, ClsOne, object)
</code></pre>
<p>例如,如果我们写(在任何类的范围之外)<code>super(ClsTwo,entity).__init__()</code>,我们得到:</p>
<pre><code>>>> super(ClsTwo,entity).__init__()
Here's One
>>> super(ClsThree,entity).__init__()
Here's Two
Here's Threee
>>> super(ClsThreee,entity).__init__()
Here's Two
>>> super(ClsFour,entity).__init__()
Here's Three
</code></pre>