2015-08-13 2 views
9

В Python 3, object есть экземпляр type и 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 также типа, что делает 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. Если он не может найти его, то в последнем случае необходимо проверить, действительно ли bobject, в этом случае функция возвращает 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).
+0

Я уверен, что вы можете эмулировать это поведение с помощью виртуальных подклассов. – Dunes

Смежные вопросы