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

Posted

技术标签:

【中文标题】Python 3:对象如何成为类型的实例?【英文标题】:Python 3: How can object be instance of type? 【发布时间】:2015-12-24 05:44:10 【问题描述】:

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

每个类怎么可能派生自另一个?

任何实现细节?

我使用isinstance(sub, base) 进行了检查,根据 Python 文档,它检查子类是否派生自基类:

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

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

【问题讨论】:

【参考方案1】:

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

Python 中的一切都是对象,所以由于 object 是一切的基本类型,type(在 Python 中是某种东西)是 object 的一个实例。 由于object 是所有事物的基本类型object 也是一个类型,这使得object 成为type 的实例。李>

请注意,这种关系在 Python 中无法用您自己的事物 复制。这是语言中内置的一个例外。


在实现方面,这两个名称分别由PyBaseObject_Typeobject)和PyType_Typetype)表示。

当您使用isinstance 时,类型检查(在最后一步,在其他所有操作都失败后)由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);

这实质上是不断上升a 的类型层次结构,并根据b 检查生成的类型。如果找不到,最后的手段是检查b 是否实际上是object,在这种情况下,函数返回true:因为一切都是对象。所以“一切都是object的实例”部分实际上是硬编码到实例检查中的。

至于为什么objecttype,这实际上更简单,因为它只是在declaration of PyBaseObject_Type 中定义的:

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)

【讨论】:

我相信您可以使用虚拟子类来模拟这种行为。

以上是关于Python 3:对象如何成为类型的实例?的主要内容,如果未能解决你的问题,请参考以下文章

python如何判断类型

如何创建对象列表?

python_26_如何派生内置不可变类型并修改实例化行为

python------面向对象介绍之多态实例

给定一个类型对象的实例,如何调用该类的构造函数(在其他语言中等效于GetConstructor)

javasript数据类型以及如何判断数据类型