所以我在Python中遇到了自定义类型,函数和属性的问题。
当我在Python中,并且我想在我的一个自定义类型(例如Vector4)上设置属性时,我的代码为const char* attribute_name
参数获取NULL(是的,我正在导入我的模块)。
奇怪的是,当我在我的setter函数中硬编码属性名称时,我收到错误:
SystemError: error return without exception set
我确实看到对象是用Python创建的(再次用C ++创建),所以我不认为这是问题所在。如果setattro钩子在C ++中成功设置了属性,我会返回1,并且我看到代码被调用并在C ++端设置属性。设置属性时不会引发任何错误/异常。
此外,当我在Python中调用我的类的实例上的函数时,它调用tp_getattro
中的函数集而不是检查字典。
我不完全确定为什么,也许是因为我设置了一个字典并将我的函数放在那里,而不是通过PyModuleDef
数组来完成,因此{{{}}时没有看到函数1}}被称为。
有谁知道为什么会这样?我们正在使用Python 3.2。
相关:
我有一个基类型(PyType_Ready
和tp_new
)然后我在运行时创建派生类型。派生类型包含字典tp_dealloc
,tp_base
和tp_getattro
。
这是函数绑定到Python类/类型的方式:
tp_setattro
其中funcName和className是const char *。 pythonFunc是一个通用的python函数,它处理调用绑定到元系统的所有函数。 classObj是一个PythonClass的指针,它有一个成员m_pyClassType(一个pyTypeObject类型)。
PyMethodDef newMethod;
newMethod.ml_doc = newMethod.ml_name = funcName;
newMethod.ml_flags = METH_VARARGS;
newMethod.ml_meth = pythonFunc;
PyGeneralObj* selfFake = PyObject_New(PyGeneralObj, &MetaEngineType);
selfFake->className = className;
selfFake->funcName = funcName;
Py_INCREF((PyObject*)selfFake);
PyObject *func = PyCFunction_New(&newMethod, (PyObject*)selfFake);
PyObject *method = PyInstanceMethod_New(func);
ErrorIf((method == NULL), "Python: Cannot create instance function. %s",
funcName);
ErrorIf((PyDict_SetItem(classObj->m_pyClassType->tp_dict,
PyReturnStr(newMethod.ml_name), method) == -1),
"Python: Cannot create function in dictionary.");
Py_DECREF(func);
Py_DECREF(method);
是一个新对象,有两个const char *和一个void *(这是C ++中的对象)
我做PyGeneralObj
并且没有错误,然后增加我的类型。然后我将对象添加到我从PyType_Ready
给出的模块PyObject中。我将我的主模块附加到运行时并初始化python并导入我的模块。
如果需要更多信息/代码,我可以发布更多信息/代码。我希望这是有道理的,这是我第一次在stackoverflow上发帖。
为了澄清,我们希望拥有在C ++端完全解析的动态属性。对于函数,我希望能够覆盖PyImport_ImportModule
参数,以便我可以获取需要调用的函数的字符串名称。
我们不想使用第三方库/接口,如Boost,Cython等等。
答案 0 :(得分:0)
问题出在我的getattro实现中。