6

我假设这个问题很复杂,但学习 OWL 为生活、宇宙和一切开辟了新的视角。我在这里谈哲学。

我正在尝试实现一个 C 类,它是 B 的子类,而 B 又是 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(它不是一种编程语言)中允许这样做而在编程语言中不允许这样做?

4

6 回答 6

10

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

也就是说,Python 中有一个特殊情况:typeobject. object是 的实例type,并且type是 的子类object。当然,type也是(因为它是 的子类)一个实例。这可能是 OWL 允许它的原因:如果您希望一切都成为对象并且所有对象都具有类,则需要在某个奇异点中启动类/元类层次结构。typeobject

于 2010-02-08T17:03:21.703 回答
2

在 Python 中实现的 MRO 方案(从 2.3 开始)禁止循环子类化。有效的 MRO 保证满足“本地优先级”和“单调性”。循环子类化会打破单调性。

这个问题在标题为“Bad Method Resolution Orders”的部分中进行了讨论

于 2010-02-08T17:08:18.357 回答
2

这种“断开”的部分原因是 OWL 描述了一个开放的世界本体。一个本体与一个程序几乎没有关系,除了一个程序可以操纵一个本体。

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

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

于 2010-02-08T18:10:09.183 回答
1

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

于 2010-02-08T17:01:30.117 回答
1

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

于 2010-02-08T20:56:20.713 回答
0

我相信有人可以举一个有意义的例子。但是,我想这个限制更容易,而不是更强大。

例如,假设类 A 包含字段 a 和 b。C类持有b和c。那么 C 对事物的看法将是:Aa、Cb、Cc,而 A 对事物的看法将是:Aa、Ab、Cc

不过,仅仅将 b 移到一个通用的基类中就更容易理解和实现了。

于 2010-02-08T17:05:51.280 回答