<p>嵌套类只是一个定义存在于另一个范围内的类。它们在Python中通常没有那么有用。然而,您可以随心所欲地从多个类的属性中派生出一个类的属性;两个主要方法是<em>mixins/multiple inheritance</em>和<em>composition</em>。在</p>
<p>混合方法如下:</p>
<pre><code>class A(object):
def __init__(self, a=None, *args, **kwargs):
self.a = a
super(A, self).__init__(*args, **kwargs)
class B(object):
def __init__(self, b=None, *args, **kwargs):
self.b = b
super(B, self).__init__(*args, **kwargs)
class X(A, B):
def __init__(self, *args, **kwargs):
super(X, self).__init__(*args, **kwargs)
x = X(a='foo', b='bar')
print x.a, x.b
</code></pre>
<ul>
<li><p>由于<code>X</code>同时具有<code>A</code>和<code>B</code>的属性,因此它继承了这两个属性:<code>class X(A, B)</code>。</p></li>
<li><p>每个<code>__init__</code>接受<code>*args, **kwargs</code>作为参数;我们在<code>X</code>中的<code>super()</code>调用将命名参数传递给<code>A</code>和<code>B</code>的初始化者,因此我们需要它能够接受(然后忽略)其他<em>初始化器的参数。也就是说,我们将<code>a</code>和<code>b</code>都传递到<code>A.__init__</code>中,但只使用<code>a</code>。</p></li>
<li><p>仔细阅读<code>super()</code>对于理解Python的继承是必不可少的。</p></li>
</ul>
<p>但是,多重继承可能很难管理过去的简单示例,因此通常建议您使用<em>组合</em>:</p>
^{pr2}$
<p>您可以看到这消除了对<code>super()</code>调用和初始化器上任何特殊参数处理的需要,使其更加清晰。这里我们取两个参数,然后在内部构造相关的类并将它们附加到<code>X</code>实例。这会使属性查找变得更加困难,但有一些方法可以简化:</p>
<pre><code>class X(object):
# <etc>
@property
def a(self):
return self.A.a
</code></pre>
<p>也可以重写<code>__getattr__</code>并执行一些动态查找,而不是手动编码每个属性。在</p>
<pre><code>class X(object):
# <etc>
def __getattr__(self, item):
for component in (getattr(self, c) for c in ['A', 'B']):
if hasattr(component, item):
return getattr(component, item)
</code></pre>
<p>另一个选项是在自己内部传递组合实例:</p>
<pre><code>class X(object):
def __init__(self, A, B):
self.A = A
self.B = B
x = X(A('foo'), B('bar'))
print x.A.a, x.B.b
</code></pre>
<p>这就不需要<code>X</code>知道<code>A</code>和{<cd3>}除了它们的接口之外的任何信息。这使得封装更容易:如果合适的话,现在可以将<code>A</code>和{<cd3>}粘贴到它们自己的模块中。为了方便起见,您还可以使用工厂函数:</p>
<pre><code>def make_X(a, b):
return X(
A(a),
B(b)
)
</code></pre>