Когда вы «присущи экземпляру», то, что вы действительно делаете, это странный способ использования метакласса. Обычно объекты класса являются экземплярами type
. В случае вышеупомянутого класса B он наследуется от экземпляра Foo
. Это именно то, что произойдет, если вы определили класс с Foo
в качестве его метакласса, а затем унаследовали от него.
Итак, мое предположение относительно того, что здесь происходит, заключается в том, что Python обрабатывает базовые классы в обратном порядке MRO.
Класс C работает, потому что первый родительский класс для обработки - Foo
, чей класс - type
. Это означает, что метакласс D должен быть type
или некоторый его подкласс. Затем обрабатывается Foo()
, чей класс Foo
, который является подклассом type
, так что все в порядке.
Класс D терпит неудачу, потому что первый родительский класс, который будет обработан, - Foo()
, который устанавливает ограничение, что у D есть метакласс Foo
(или подкласс). Затем приходит Foo
, чей класс type
равен , а не подкласс Foo
.
Это полное предположение, но вы можете попытаться выяснить, требует ли документация Python по метаклассам, когда вы умножаете наследование от двух классов с разными метаклассами, где у задействованных метаклассов есть отношение подтипа, что вы размещаете их в определенном порядке. .