2015-08-13 26 views
9

在Python 3中,objecttype的一个实例,而type也是object的一个实例!Python 3:对象如何可以是类型的实例?

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

任何实现细节?

我检查此使用isinstance(sub, base),其中,根据Python文档,检查是否子类是从基类派生:

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

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

回答

16

这是对边缘情况在Python之一:

  • Python中的所有东西都是一个对象,因此object是一切的基本类型,type(在Python中是东西)是object的一个实例。
  • 由于object是基本类型一切object也是一个类型,这使得objecttype一个实例。

注意,这种关系是什么,你可以使用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的实例”部分实际上是硬编码到实例检查中的。

至于为什么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)
+0

我相信你可以用虚拟子类来模拟这种行为。 – Dunes

相关问题