In Python 3, object
is an instance of type
and type
is also an instance of object
!
How is it possible that each c
This is one of the edge cases in Python:
object
is the base type of everything, type
(being something in Python) is an instance of object
.object
is the base type of everything, object
is also a type, which makes object
an instance of type
.Note that this relationship is nothing you can replicate with your own things in Python. It’s a single exception that is built into the language.
On the implementation side, the two names are represented by PyBaseObject_Type
(for object
) and PyType_Type
(for type
).
When you use isinstance
, the type check—in the very last step, after everything else has failed—is done by 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);
}
This essentially keeps going up the type hierarchy of a
and checks the resulting type against b
. If it cannot find one, then the last resort is to check whether b
is actually object
in which case the function returns true: since everything is an object. So the “everything is an instance of object
” part is actually hardcoded into the instance check.
And as for why object
is a type
, this is actually even simpler because it’s simply defined that way in the declaration of PyBaseObject_Type:
PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
sizeof(PyObject), /* tp_basicsize */
…
The PyVarObject_HEAD_INIT
essentially sets the core type information stuff, including the base type, which is PyType_Type
.
There are actually two more consequences of this relationship:
object
is also an instance of object
: isinstance(object, object)
PyType_Type
is also implemented with the same PyVarObject_HEAD_INIT
, type
is also a type: isinstance(type, type)
.