Python 3:对象如何成为类型的实例?
Posted
技术标签:
【中文标题】Python 3:对象如何成为类型的实例?【英文标题】:Python 3: How can object be instance of type? 【发布时间】:2015-12-24 05:44:10 【问题描述】:在 Python 3 中,object
是 type
的实例,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_Type
(object
)和PyType_Type
(type
)表示。
当您使用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
的实例”部分实际上是硬编码到实例检查中的。
至于为什么object
是type
,这实际上更简单,因为它只是在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:对象如何成为类型的实例?的主要内容,如果未能解决你的问题,请参考以下文章