<p>我发现自己处于钻石继承的奇怪境地,更糟糕的是钻石中间的类共享一个成员。下面我展示了一段代码,它突出了我的问题。在</p>
<p>我在编写我从<a href="http://rhettinger.wordpress.com/2011/05/26/super-considered-super/" rel="nofollow">http://rhettinger.wordpress.com/2011/05/26/super-considered-super/</a>学到的类时使用的方法,该方法链接在python文档站点上,用于内置函数<code>super</code></p>
<pre><code>class A(object):
pass
class B(A):
def __init__(self, z=None, **kwargs):
self.z = z
super(B, self).__init__(**kwargs)
# super(B, self).__init__(z=z, **kwargs)
class C(A):
def __init__(self, z=None, **kwargs):
self.z = z
super(C, self).__init__(**kwargs)
class D(B, C):
pass
d = D(z='y')
for arg, value in d.__dict__.iteritems():
print arg, ':', value
</code></pre>
<p>产生输出</p>
^{pr2}$
<p>问题是,使用关键字参数来确保函数签名匹配的方法从类C的init调用中去掉了z参数。我可以强制地将参数添加回kwargs中(见注释代码),但这会导致我无法实例化类型为B的对象,因为这将导致对不带参数的object的init的调用,这是一个很好的特性,因为它可以防止我在实例化以下任何对象时输入无效的参数。在</p>
<p>我还注意到,如果在设置变量之前有一行super,那么问题就解决了,因为最高级别的对象将覆盖较低级别的对象。然而,我的代码主要是围绕着在末尾有超级代码而构建的,因为所有实际的“设置”都是由低级别的类执行的,而高级别的类则将值传递给继承链。是否有指导方针,以适应家长电话?在</p>
<p>有什么想法吗?在</p>
<p>谢谢</p>
<p>这是不是一个糟糕的“合作班”设计?什么是合作班?有没有应该遵循的规则或准则?在</p>
<p>编辑:</p>
<p>Stackoverflow不让我回答自己的问题,但我想出了一个解决方案。在</p>
<p>我认为合作班之间不应该有任何共享成员。如果有两个相互独立的类(在某种意义上没有“是一种”关系)共享一个成员,那么您应该在继承关系中添加一个抽象级别。在</p>
<p>共享成员应取出并放入一个单独的类中,该类继承自共享基类,并由菱形中的类继承。在</p>
<p>下面是正确的代码。为了与OP中的链接保持一致,我引入了一个根基类</p>
<p>我应该指出的是,我没有受过正规的编程教育(就像这里的大多数人一样),所以如果我使用了错误的术语,我很抱歉。在</p>
<pre><code>class Root(object):
pass
class A(Root):
pass
class HasAZ(Root):
def __init__(self, z=None, **kwargs):
self.z = z
super(HasAZ, self).__init__(**kwargs)
class B(HasAZ, A):
pass
class C(HasAZ, A):
pass
class D(B, C):
pass
d = D(z='y')
for arg, value in d.__dict__.iteritems():
print arg, ':', value
</code></pre>