自己的类子类。为什么禁止相互子类化?

时间:2010-02-08 16:57:23

标签: python class owl

复杂的问题我想,但是研究OWL为生活,宇宙和一切开辟了新的视角。我在这里要有哲学。

我正在尝试实现一个C类,它是B的子类,而C又是C的子类。只是为了好玩,你知道......

所以这是

>>> class A(object): pass
... 
>>> class B(A): pass
... 
>>> class C(B): pass
... 
>>> B.__bases__
(<class '__main__.A'>,)
>>> B.__bases__ = (C,)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a __bases__ item causes an inheritance cycle
>>> 
很明显,python很聪明并禁止这样做。但是,在OWL中,可以将两个类定义为相互子类。问题是:为什么在OWL(不是一种编程语言)中允许这种情况并且在编程语言中不允许使用它是什么令人难以置信的解释?

6 个答案:

答案 0 :(得分:9)

Python不允许它,因为没有合理的方法来做到这一点。你可以发明关于如何处理这种情况的任意规则(也许某些语言会这样做),但由于这样做没有实际的好处,Python拒绝猜测。由于多种原因,类需要具有稳定,可预测的方法解析顺序,因此不允许使用奇怪的,不可预测的或令人惊讶的MRO。

也就是说, 是Python中的一个特例:typeobjectobjecttype的实例,typeobject的子类。当然,type 也是 type的一个实例(因为它是object的子类)。这可能是OWL允许它的原因:如果你想要一切都是一个对象而所有对象都有一个类,你需要在一些奇点中启动一个类/元类层次结构。

答案 1 :(得分:2)

用Python实现的MRO方案(截至2.3)禁止循环子类化。有效的MRO保证满足“本地优先级”和“单调性”。循环子类化将破坏单调性。

此问题在标题为"Bad Method Resolution Orders"

的部分中讨论

答案 2 :(得分:2)

这种“脱节”的部分原因是因为OWL描述了一个开放的世界本体论。除了程序可以操作本体之外,本体论与程序几乎没有任何关系。

尝试将OWL概念与编程语言联系起来就像试图将A Pianist和A Piano Sonata联系起来。

奏鸣曲在有人演奏之前并没有真正的具体表现 - 最好是钢琴家,但不一定。在它被播放之前,它只是表达为声音的音符之间的潜在的关系。当它被播放时,一些实际的关系将与你,听众有关。有些与听众无关。

答案 3 :(得分:1)

我认为答案是“当你构造C类时......它必须创建B类的实例..它必须创建C类的实例......依此类推”这将永远不会结束。这在大多数语言中是被禁止的(事实上我不知道其他情况)。 您只能创建一个对象,该对象具有对其他对象的“引用”,该对象最初可以为null。

答案 4 :(得分:1)

对于语义推理器,如果A是B的子类,而B是A的子类,则可以认为这些类是等价的。它们不是“相同的”,但从推理的角度来看,如果我可以推断个人是(或不是)A类的成员,我可以推断个人是(或不是)B类的成员A类和B类在语义上是等价的,这是你能用OWL表达的。

答案 5 :(得分:0)

我确信有人可以举出一个有意义的例子。但是,我认为这种限制更容易,而且不那么强大。

例如,假设A类包含字段a和b。 C类持有b和c。那么来自C的事物的观点将是:A.a,C.b,C.c和来自A的视图将是:A.a,A.b,C.c。

但是,将b移动到公共基类中更容易理解和实现。