Python 3: How can object be instance of type?

谁说我不能喝 提交于 2019-11-26 17:02:13

问题


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

回答1:


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).


来源:https://stackoverflow.com/questions/31995472/python-3-how-can-object-be-instance-of-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!