一个类为何不能自我子类化?为什么禁止互相子类化?

6 投票
6 回答
1923 浏览
提问于 2025-04-15 19:02

这个问题可能有点复杂,但学习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(这不是一种编程语言)中允许这样,而在编程语言中却不允许呢?

6 个回答

2

这种“脱节”的一部分是因为OWL描述的是一个开放的世界本体。简单来说,本体和程序的关系不大,程序只是可以操作本体而已。

把OWL的概念和编程语言联系起来,就像把钢琴家和钢琴奏鸣曲联系在一起一样。

奏鸣曲在没有人演奏的时候,其实并没有具体的表现——理想情况下是由钢琴家来演奏,但不一定非得是他。直到有人演奏,它才会变成音符之间的潜在关系,变成声音。当有人演奏时,听众能感受到的关系中,有些是相关的,有些则不相关。

2

在Python(从2.3版本开始)中,MRO(方法解析顺序)规则不允许循环继承。有效的MRO必须满足“局部优先级”和“单调性”。如果允许循环继承,就会破坏这种单调性。

这个问题在标题为 “糟糕的方法解析顺序” 的部分中有讨论。

10

Python不允许这样做,因为没有合理的方法来处理这种情况。你可以随便制定一些规则来处理这种情况(可能有些语言确实这样做),但因为这样做没有实际的好处,所以Python不愿意去猜测。类需要有一个稳定、可预测的方法解析顺序,这样做有很多原因,因此奇怪、不稳定或让人意外的方法解析顺序是被禁止的。

不过,Python中确实有一个特殊的情况:typeobjectobjecttype的一个实例,而type又是object的一个子类。当然,type也是type的一个实例(因为它是object的子类)。这可能就是为什么OWL允许这样做的原因:如果你想让所有东西都是对象,并且所有对象都有一个类,你需要在某个特殊的地方开始一个类/ metaclass的层次结构。

撰写回答