【问题标题】:A class subclass of itself. Why mutual subclassing is forbidden?自身的类子类。为什么禁止相互子类化?
【发布时间】:2011-01-14 11:07:18
【问题描述】:

我认为这个问题很复杂,但学习 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(它不是一种编程语言)中允许这样做而在编程语言中不允许这样做,令人难以置信的解释是什么?

【问题讨论】:

    标签: python class owl


    【解决方案1】:

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

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

    【讨论】:

    • 您表示不存在相互继承的一致规则集。你能详细说明为什么会这样吗?
    • 我不打算表明这一点。 MI 的一致规则集确实存在。 Python 遵循 MI 的 C3 算法。 MI 层次结构基本上是扁平化的,以创建一个明智的(和可预测的)MRO。但是,C3 禁止模棱两可的情况,例如继承循环和基类之间的基类顺序不一致。
    【解决方案2】:

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

    这个问题在标题为"Bad Method Resolution Orders"的部分中讨论

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 我现在做的是根据本体描述实体。这些实体映射到类。当然,如果本体包含相互的子类,我无法将这些猫头鹰类映射到程序类。我知道我使用了错误的方法,但目前,凭借我拥有的资源、我拥有的限制和我拥有的时间,这是我能做的最好的事情。好在我没有这种情况,而且我的本体很简单,所以我可以手工制作类映射。
      • 大多数时候,我们在代码外部定义实体和本体。我们编写代码来推理实体,使用本体规则对实体进行分类。您的基本问题源于观察到本体比 OO 编程语言更丰富。这指出了尝试从本体生成代码的问题。从本体生成代码只能通过在创建代码时使用本体来指导推理来完成。
      • 谢谢@S.Lott,你的评论很有趣。
      【解决方案4】:

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

      【讨论】:

      • 不,子类化在 Python 中不起作用。子类的实例不创建或包含超类的实例。
      • 有点意思……如果我听到你说的话,那是因为你有代码要执行,而 OWL 只与实体之间的逻辑关系描述有关。在后一种情况下,相互子类化不会引入任何歧义,只会在逻辑级别进行处理。
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        我相信有人可以举一个有意义的例子。不过,我想这个限制更简单,而且威力也不会减弱。

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

        不过,将 b 移到一个通用基类中要容易得多。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-17
          • 2011-07-01
          • 1970-01-01
          • 2016-03-30
          • 2011-12-15
          • 1970-01-01
          • 1970-01-01
          • 2019-08-06
          相关资源
          最近更新 更多