Python 3: How can object be instance of type?

后端 未结 1 1246
臣服心动
臣服心动 2020-12-03 18:16

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

How is it possible that each c

相关标签:
1条回答
  • 2020-12-03 18:39

    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).
    0 讨论(0)
提交回复
热议问题