Python 3:对象如何成为类型的实例?

Python 3: How can object be instance of type?

在python 3中,objecttype的实例,type也是object的实例!

每个类是如何从另一个类派生的?

有实施细节吗?

我使用isinstance(sub, base)检查了这个问题,根据python文档,它检查子类是否派生自基类:

1
2
3
4
5
isinstance(object, type)
Out[1]: True

isinstance(type, object)
Out[2]: True

这是Python中的一个边缘案例:

  • python中的所有内容都是一个对象,因此由于object是所有内容的基本类型,因此type(在python中是某种内容)是object的一个实例。
  • 由于object是万物的基型,object也是一种类型,使object成为type的实例。

请注意,在Python中,这种关系是无法用自己的东西进行复制的。这是语言中的一个例外。

在实施方面,这两个名称分别由PyBaseObject_Type(用于object)和PyType_Type(用于type)表示。

当您使用isinstance时,在所有其他操作失败后,最后一步中的类型签入由type_is_subtype_base_chain执行:

1
2
3
4
5
6
7
8
9
10
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);
}

这基本上是在a的类型层次结构上进行的,并对照b检查生成的类型。如果找不到,那么最后一个办法就是检查b是否实际是object,在这种情况下,函数返回true:因为一切都是对象。所以"一切都是object的一个实例"部分实际上是硬编码到实例检查中的。

至于为什么objecttype的原因,这实际上更简单,因为在PyBaseObject_Type的声明中简单地定义了这一点:

1
2
3
4
5
PyTypeObject PyBaseObject_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
   "object",                                   /* tp_name */
    sizeof(PyObject),                           /* tp_basicsize */
    …

PyVarObject_HEAD_INIT本质上是设置核心类型信息的东西,包括基本类型,即PyType_Type

这种关系实际上还有两个后果:

  • 因为一切都是对象,所以object也是object的实例:isinstance(object, object)
  • 由于PyType_Type也与同一PyVarObject_HEAD_INIT一起实施,type也是一种类型:isinstance(type, type)