Questo è uno dei casi limite in Python:
- Tutto in Python è un oggetto, quindi dal momento che
object
è il tipo di base di tutto, type
(essendo qualcosa in Python) è un'istanza di object
.
- Poiché
object
è la base tipo di tutto, object
è anche un tipo, che rende object
un'istanza di type
.
Si noti che questo rapporto è nulla è possibile replicare con i propri cose in Python. È una singola eccezione incorporata nella lingua.
Sul lato attuazione, i due nomi sono rappresentati da PyBaseObject_Type
(per object
) e PyType_Type
(per type
).
Quando si utilizza isinstance
, il tipo di check-in l'ultimo passo, dopo tutto il resto ha fallito-è fatto da 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);
}
Ciò mantiene sostanzialmente risalendo il tipo gerarchia dei a
e controlla la tipo risultante contro b
. Se non riesce a trovarne uno, l'ultima risorsa è verificare se b
è in realtà object
nel qual caso la funzione restituisce true: poiché tutto è un oggetto. Quindi la parte "tutto è un'istanza di object
" è effettivamente codificata nel controllo dell'istanza.
E per quanto riguarda il motivo per cui object
è un type
, questo è in realtà ancora più semplice perché è semplicemente definito in quel modo nel declaration of PyBaseObject_Type
:
PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
sizeof(PyObject), /* tp_basicsize */
…
Il PyVarObject_HEAD_INIT
imposta essenzialmente la roba informazioni sul tipo di base, tra cui il tipo di base, che è PyType_Type
.
realtà ci sono altri due conseguenze di questa relazione:
- Poiché tutto è un oggetto,
object
è anche un'istanza di object
: isinstance(object, object)
- Da
PyType_Type
è implementata anche con la stessa PyVarObject_HEAD_INIT
, type
è anche un tipo: isinstance(type, type)
.
Sono sicuro che è possibile emulare questo comportamento con sottoclassi virtuali. – Dunes