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