Конфликт метакласса, множественное наследование и экземпляр в качестве родительского

Я возился с темными искусствами Python и там кое-что, что мне хотелось бы помочь понять. Учитывая класс Foo, здесь некоторые способы, которые я пытался наследовать от него:

  • class A(Foo) — Работает, неудивительно.
  • class B(Foo()) — предоставленные работы Foo имеет соответствующий метод __new__ (который я предоставил)
  • class C(Foo(), Foo) — работает на тех же условиях, что и B
  • class D(Foo, Foo()) — дает известную ошибку метакласса:

    Traceback (последний последний звонок):
        Файл "test.py", строка 59, в
            класс n (Foo, Foo()):
    TypeError: конфликт метакласса: метакласс производного класса должен быть (нестрогим) подкласс метаклассов всех его оснований

Что именно это вызывает этот конфликт? Когда я наследую от (Foo(), Foo) (сначала экземпляр, второй класс), он работает, но когда я наследую от (Foo, Foo()) (сначала класс, второй экземпляр), это не так.

+4
источник поделиться
1 ответ

Когда вы "присущи экземпляру", то, что вы действительно делаете, - это странный способ использования метакласса. Обычно объекты класса являются экземплярами type. В случае класса B выше он наследуется от экземпляра Foo. Это именно то, что произойдет, если вы определили класс с Foo как его метакласс, а затем унаследовали от него.

Итак, мое предположение о том, что происходит здесь, заключается в том, что Python обрабатывает базовые классы в обратном порядке MRO.

Класс C работает, потому что первый родительский класс, который должен быть обработан, Foo, класс которого type. Это означает, что метакласс D должен быть type или некоторым подклассом. Затем обрабатывается Foo(), класс которого Foo, который является подклассом type, поэтому все отлично.

Класс D не работает, поскольку первый родительский класс, который должен быть обработан, Foo(), который устанавливает ограничение, что D имеет метакласс из Foo (или подкласс). Затем идет Foo, класс type не является подклассом Foo.

Это полная догадка, но вы можете попробовать и посмотреть, требуется ли документация Python для метаклассов при умножении наследования на два класса с разными метаклассами, где задействованные метаклассы имеют отношение подтипа, которое вы помещаете в определенный порядок.

+5
источник

Посмотрите другие вопросы по меткам или Задайте вопрос