我想检查一个对象是否是某个类的实例。在Python中,我可以使用instanceof
来做到这一点。在C / C ++中,我发现了一个名为PyObject_IsInstance的函数。但这似乎不像isinstance
那样起作用。
详细信息(以下也称为示例代码):
My
。类型定义为MyType
,对象定义为MyObject
。MyType
添加到名称为My
的导出模块中。my = My()
,然后isinstance(my, My)
返回True
。PyObject_IsInstance(my, (PyObject*)&MyType)
检查my
,并返回0
,这意味着my
不是{{1}定义的类的实例}。完整的C ++代码:
MyType
将其编译为#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;
}
,并在Python中对其进行测试:
cpp.so
答案 0 :(得分:1)
这是典型的调用约定,其中方法的类型为PyCFunction。该函数需要两个
PyObject*
值。第一个是方法的自我对象;第二个是方法的自我对象。对于模块功能,它是模块对象。第二个参数(通常称为args)是表示所有参数的元组对象。通常使用PyArg_ParseTuple()
或PyArg_UnpackTuple()
处理此参数。
Py_fn_checkMy
的功能签名与此不匹配。它需要两个参数。第一个是模块,这就是您要检查的MyType
。第二个参数(您实际上并不接受)是一个包含您传递的对象的元组。您应该从元组中提取参数,并检查其类型。
使用METH_O
指定单个参数而不是从元组提取参数可能会更好:
static PyObject *Py_fn_checkMy(PyObject *self, PyObject *obj) {
if (PyObject_IsInstance(obj, (PyObject *)&MyType)) Py_RETURN_TRUE;
else Py_RETURN_FALSE;
}
static PyMethodDef modmethodsdef[] = {
{ "checkMy", (PyCFunction)Py_fn_checkMy, METH_O, NULL },
{ NULL }
};