Подкласс самого себя. Почему взаимный подкласс запрещен?

Сложный вопрос, я полагаю, но изучение OWL открыло новую перспективу жизни, Вселенной и всего остального. Я тут философствую.

Я пытаюсь получить класс C, который является подклассом 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 (который не является языком программирования) и запрещено в языках программирования?


person Stefano Borini    schedule 08.02.2010    source источник


Ответы (6)


Python не позволяет этого, потому что нет разумного способа сделать это. Вы можете изобрести произвольные правила о том, как обрабатывать такой случай (и, возможно, некоторые языки так и делают), но поскольку в этом нет реальной выгоды, Python отказывается гадать. Классы должны иметь стабильный, предсказуемый порядок разрешения методов по ряду причин, поэтому странные, непредсказуемые или удивительные MRO не допускаются.

При этом в Python есть особый случай: type и object. object является экземпляром type, а type является подклассом object. И, конечно же, type является также экземпляром type (поскольку это подкласс object). Возможно, поэтому OWL позволяет это: вам нужно начать иерархию классов/метаклассов в какой-то сингулярности, если вы хотите, чтобы все было объектом и все объекты имели класс.

person Thomas Wouters    schedule 08.02.2010
comment
Вы указываете, что не существует согласованного набора правил для взаимного наследования. Можете ли вы уточнить, почему это так? - person bayer; 08.02.2010
comment
Я не собираюсь это указывать. Согласованный набор правил для MI существует. Python следует алгоритму C3 для MI. Иерархия MI в основном сглажена для создания разумного (и предсказуемого) MRO. Однако C3 запрещает двусмысленные ситуации, такие как циклы наследования и непоследовательный порядок базовых классов между базовыми классами. - person Thomas Wouters; 08.02.2010

Схема MRO, реализованная в Python (начиная с версии 2.3), запрещает циклическое создание подклассов. Действительные MRO гарантированно удовлетворяют «локальному приоритету» и «монотонности». Циклическое создание подклассов нарушило бы монотонность.

Эта проблема обсуждается в разделе, озаглавленном "Правила разрешения неверных методов".

person unutbu    schedule 08.02.2010

Частично это «отключение» связано с тем, что OWL описывает онтологию открытого мира. Онтология практически не имеет ничего общего с программой, за исключением того, что программа может манипулировать онтологией.

Попытка связать концепции OWL с языками программирования подобна попытке связать «Пианиста» и «Сонату для фортепиано».

Соната на самом деле не имеет конкретного воплощения, пока кто-то ее не играет — в идеале пианист, но не обязательно. Пока он не сыгран, это всего лишь потенциальные отношения между нотами, проявленными в виде звуков. Когда он будет проигрываться, вам, слушателю, будут важны некоторые реальные отношения. Некоторые из них не будут иметь отношения к слушателю.

person S.Lott    schedule 08.02.2010
comment
Что я делаю прямо сейчас, так это то, что описываю сущности в соответствии с онтологией. Эти сущности сопоставляются с классами. Конечно, если онтология содержит взаимные подклассы, я не могу сопоставить эти классы совы с классами программы. Я знаю, что использую неправильный подход, но на данный момент, с имеющимися у меня ресурсами, ограничениями и временем, которое у меня есть, это лучшее, что я могу сделать. К счастью, у меня нет таких случаев, и моя онтология проста, поэтому я могу создать отображение классов вручную. - person Stefano Borini; 09.02.2010
comment
В большинстве случаев мы определяем наши сущности и онтологии вне нашего кода. Мы пишем наш код, чтобы рассуждать о сущностях, используя правила онтологии для классификации сущностей. Ваш фундаментальный вопрос проистекает из наблюдения, что онтология богаче, чем язык объектно-ориентированного программирования. Это указывает на проблему попытки сгенерировать код из онтологии. Генерация кода из онтологии только может быть выполнена с использованием онтологии в качестве руководства к рассуждениям при создании кода. - person S.Lott; 09.02.2010
comment
Спасибо @S.Lott, ваш комментарий был очень интересным. - person Stefano Borini; 23.02.2010

Я думаю, что ответ таков: «Когда вы создаете класс C... он должен создать экземпляр класса B.. который должен создать экземпляр класса C... и так далее». Это никогда не закончится. Это запрещено на большинстве языков (на самом деле я не знаю другого случая). Вы можете создать объект только со «ссылкой» на другой объект, который изначально может быть нулевым.

person anthares    schedule 08.02.2010
comment
Нет, в Python создание подклассов не работает. Экземпляр подкласса не создает и не содержит экземпляр суперкласса. - person Thomas Wouters; 08.02.2010
comment
в этом есть смысл... если я слышу, что вы говорите, это потому, что у вас есть код для выполнения, в то время как OWL связан только с описанием логических отношений между сущностями. в последнем случае взаимный подкласс не вносит никакой двусмысленности, он просто обрабатывается на логическом уровне. - person Stefano Borini; 08.02.2010

Для семантического рассудка, если A является подклассом B, а B является подклассом A, то классы можно считать эквивалентными. Они не «одинаковые», но с точки зрения рассуждений, если я могу сделать вывод, что человек является (или не является) членом класса A, я могу сделать вывод, что этот человек является (или не является) членом класса B. Классы A и B семантически эквивалентны, что вы и смогли выразить с помощью OWL.

person Phil M    schedule 08.02.2010

Я уверен, что кто-то может привести пример, где это имеет смысл. Однако я предполагаю, что это ограничение проще и не менее мощно.

Например, допустим, класс A содержит поля a и b. Класс C содержит b и c. Тогда точка зрения на вещи со стороны С будет: А.а, С.б, С.с, а точка зрения со стороны А будет: А.а, А.б, С.с.

Однако простое перемещение b в общий базовый класс гораздо проще для понимания и реализации.

person bayer    schedule 08.02.2010