Это одна из крайних случаев в Python:
- Все в Python является объектом, так как
object
является базовым типом всего, type
(будучи чем-то в Python) является экземпляром object
.
- Поскольку
object
является базовым типом всего, object
также типа, что делает object
экземпляр type
.
Обратите внимание, что эти отношения ничего вы можете повторить со своими собственными вещами в Python. Это единственное исключение, которое встроено в язык.
На стороне реализации, два имени представлены PyBaseObject_Type
(для object
) и PyType_Type
(для type
).
При использовании isinstance
, тип проверки, в самом последнем этапе, после того, как все остальное не удалось, делается type_is_subtype_base_chain
:
type_is_subtype_base_chain(PyTypeObject *a, PyTypeObject *b)
{
do {
if (a == b)
return 1;
a = a->tp_base;
} while (a != NULL);
return (b == &PyBaseObject_Type);
}
Это по существу продолжает идти вверх по иерархии типов в a
и проверяет в результате тип против b
. Если он не может найти его, то в последнем случае необходимо проверить, действительно ли b
object
, в этом случае функция возвращает true: поскольку все является объектом. Таким образом, «все является экземпляром object
» часть действительно жестко закодирована в проверку экземпляра.
И как почему object
является type
, это на самом деле даже проще, потому что это просто определено, что путь в declaration of PyBaseObject_Type
:
PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
sizeof(PyObject), /* tp_basicsize */
…
PyVarObject_HEAD_INIT
по существу устанавливает информационный материал ядра типа, в том числе базового типа, который составляет PyType_Type
.
Есть на самом деле еще два последствия этих отношений:
- Поскольку все является объектом,
object
также является экземпляром object
: isinstance(object, object)
- Поскольку
PyType_Type
также реализуется с той же PyVarObject_HEAD_INIT
, type
является также тип: isinstance(type, type)
.
Я уверен, что вы можете эмулировать это поведение с помощью виртуальных подклассов. – Dunes