10

In Python 3, object is an instance of type and type is also an instance of object!

How is it possible that each class is derived from the other?

Any implementation details?

I checked this using isinstance(sub, base), which, according to Python documentation, checks if sub class is derived from base class:

isinstance(object, type)
Out[1]: True
isinstance(type, object)
Out[2]: True
Michael B. Currie
14.8k11 gold badges48 silver badges61 bronze badges
asked Aug 13, 2015 at 18:07
0

1 Answer 1

19

This is one of the edge cases in Python:

  • Everything in Python is an object, so since object is the base type of everything, type (being something in Python) is an instance of object.
  • Since 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:

  • Since everything is an object, object is also an instance of object: isinstance(object, object)
  • Since PyType_Type is also implemented with the same PyVarObject_HEAD_INIT, type is also a type: isinstance(type, type).
answered Aug 13, 2015 at 18:12
Sign up to request clarification or add additional context in comments.

1 Comment

I'm sure you could emulate this behaviour with virtual subclasses.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.