Я хочу проверить, является ли объект экземпляром определенного класса.В Python я могу сделать это с instanceof
.В C / C ++ я нашел функцию с именем PyObject_IsInstance .Но, похоже, он не работает, как isinstance
.
Подробно (также описанный ниже в качестве примеров кода):
- В C ++ я определил свой пользовательский тип
My
.Определение типа - MyType
, а определение объекта - MyObject
. - Добавьте
MyType
в экспортируемый модуль с именем My
. - В Python создайте новый экземпляр
my = My()
и isinstance(my, My)
возвращает True
. - В то время как в C ++ мы используем
PyObject_IsInstance(my, (PyObject*)&MyType)
для проверки my
, и это возвращает 0
, что означает, что my
не является экземпляромкласс, определенный как MyType
.
Полный код C ++:
#define PY_SSIZE_T_CLEAN
#include <python3.6/Python.h>
#include <python3.6/structmember.h>
#include <stddef.h>
typedef struct {
PyObject_HEAD
int num;
} MyObject;
static PyTypeObject MyType = []{
PyTypeObject ret = {
PyVarObject_HEAD_INIT(NULL, 0)
};
ret.tp_name = "cpp.My";
ret.tp_doc = NULL;
ret.tp_basicsize = sizeof(MyObject);
ret.tp_itemsize = 0;
ret.tp_flags = Py_TPFLAGS_DEFAULT;
ret.tp_new = PyType_GenericNew;
return ret;
}();
// check if obj is an instance of MyType
static PyObject *Py_fn_checkMy(PyObject *obj) {
if (PyObject_IsInstance(obj, (PyObject *)&MyType)) Py_RETURN_TRUE;
else Py_RETURN_FALSE;
}
static PyMethodDef modmethodsdef[] = {
{ "checkMy", (PyCFunction)Py_fn_checkMy, METH_VARARGS, NULL },
{ NULL }
};
static PyModuleDef moddef = []{
PyModuleDef ret = {
PyModuleDef_HEAD_INIT
};
ret.m_name = "cpp";
ret.m_doc = NULL;
ret.m_size = -1;
return ret;
}();
PyMODINIT_FUNC
PyInit_cpp(void)
{
PyObject *mod;
if (PyType_Ready(&MyType) < 0)
return NULL;
mod = PyModule_Create(&moddef);
if (mod == NULL)
return NULL;
Py_INCREF(&MyType);
PyModule_AddObject(mod, "My", (PyObject *)&MyType);
PyModule_AddFunctions(mod, modmethodsdef);
return mod;
}
Скомпилируйте это в cpp.so
и протестируйте в Python:
>>> import cpp
>>> isinstance(cpp.My(), cpp.My)
True
>>> cpp.checkMy(cpp.My())
False