С точки зрения семантики языка, type
и object
существуют, полностью инициализированные, с момента запуска программы.Что бы реализация ни делала, чтобы привести вещи в это состояние, не обязательно должно следовать правилам того, что реализация позволяет you .
С точки зрения реализации CPython как type
, так иobject
статически размещаются на уровне C, и ни один из них не создается первым.Вы можете увидеть определения переменных в Objects/typeobject.c
. Здесь object
:
PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
sizeof(PyObject), /* tp_basicsize */
0, /* tp_itemsize */
object_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
object_repr, /* tp_repr */
...
};
и здесь type
:
PyTypeObject PyType_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"type", /* tp_name */
sizeof(PyHeapTypeObject), /* tp_basicsize */
sizeof(PyMemberDef), /* tp_itemsize */
(destructor)type_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)type_repr, /* tp_repr */
...
};
Когда начинается инициализация интерпретатора, оба type
object
находятся в полуинициализированном состоянии, а функция PyType_Ready
отвечает за завершение их инициализации.Указатели типов устанавливаются в определениях переменных, но установка указателей суперкласса является частью работы PyType_Ready
, и множество других инициализаций должны обрабатываться PyType_Ready
- например, типы не имеют__dict__
пока.
Кстати, используя некоторые странные метаклассы и тот факт, что Python позволяет переназначать __class__
для экземпляров пользовательских классов, мы можем настроить наши собственные классы A
и B
, где B
является подклассом A
, а оба A
и B
являются экземплярами B
, очень похоже на ситуацию с object
и type
.Это не похоже на то, как на самом деле создаются object
и type
, хотя:
class DummyMeta(type):
pass
class A(type, metaclass=DummyMeta):
pass
class B(A):
pass
B.__class__ = B
A.__class__ = B
print(isinstance(A, B))
print(isinstance(B, B))
print(issubclass(B, A))
Вывод:
True
True
True