Dieser Artikel befasst sich hauptsächlich mit dem Problem der Überlastung der Vererbungsbeziehung. Jetzt können Freunde in Not auf die Vererbungsbeziehung zurückgreifen
Mit der integrierten Methode isinstance(object, classinfo) können Sie feststellen, ob ein Objekt eine Instanz einer bestimmten Klasse ist. Diese Beziehung kann direkt, indirekt oder abstrakt sein.
Der hier vorgeschlagene primäre Mechanismus besteht darin, das Überladen der integrierten Funktionen isinstance() und issubclass() zu ermöglichen. Das Überladen funktioniert wie folgt: Der Aufruf isinstance(x , C) prüft zunächst, ob C.__instancecheck__ existiert, und ruft in diesem Fall C.__instancecheck__(x) anstelle seiner normalen Implementierung auf. , C) Bei der Erkennung wird zunächst geprüft, ob C.__instancecheck__ existiert .__instancecheck__(x) wird aufgerufen. Das zurückgegebene Ergebnis ist das Ergebnis der Instanzerkennung, und es gibt keine Standardbeurteilungsmethode.
Diese Methode hilft uns, die Enteneingabe zu überprüfen. Ich habe sie mit Code getestet.Es wird nur False ausgegeben und __instancecheck__ wird nicht aufgerufen. Was ist los.
class Sizeable(object): def __instancecheck__(cls, instance): print("__instancecheck__ call") return hasattr(instance, "__len__") class B(object): pass b = B() print(isinstance(b, Sizeable)) # output:FalseNach dem Login kopieren
Es gibt keinen laufenden __instancecheck__
Es ist ersichtlich, dass das Dokument nicht klar geschrieben ist. Um das Problem herauszufinden, beginnen wir mit der Nachverfolgung der isinstance-Quellcode.
[abstract.c]
int
PyObject_IsInstance(PyObject *inst, PyObject *cls)
{
_Py_IDENTIFIER(__instancecheck__);
PyObject *checker;
/* Quick test for an exact match */
if (Py_TYPE(inst) == (PyTypeObject *)cls)
return 1;
....
}
/* We know what type's __instancecheck__ does. */ if (PyType_CheckExact(cls)) { return recursive_isinstance(inst, cls); }
[object.h] #define PyType_CheckExact(op) (Py_TYPE(op) == &PyType_Type)
def recursive_isinstance(inst, cls): return pyType_IsSubtype(inst, cls) def pyType_IsSubtype(a, b): for mro in a.__mro__: if mro is b: return True return False
if (PyTuple_Check(cls)) { ... }
checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__); if (checker != NULL) { res = PyObject_CallFunctionObjArgs(checker, inst, NULL); ok = PyObject_IsTrue(res); return ok; }
[typeobject.c] PyObject * _PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid) { PyObject *res; res = _PyType_LookupId(Py_TYPE(self), attrid); // 有回调的话处理回调 // ... return res; }
Zusammenfassung
An dieser Stelle fassen Sie die Bedingungen für das Überlastungsverhalten von isinstance(x, C) zusammen:
x-Objekte können nicht direkt von C instanziiert werden;
class MetaSizeable(type): def __instancecheck__(cls, instance): print("__instancecheck__ call") return hasattr(instance, "__len__") class Sizeable(metaclass=MetaSizeable): pass class B(object): pass b = B() print(isinstance(b, Sizeable)) # output: False print(isinstance([], Sizeable)) # output: True
Verwandte Empfehlungen:
Detaillierte Erklärung von read_excel in Python 2.7 Pandas
Das obige ist der detaillierte Inhalt vonEine kurze Diskussion zum Problem der Überlastung istInstanzvererbungsbeziehung in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!