所以我在 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
数组来完成,因此在PyType_Ready
调用时看不到函数。
有谁知道为什么会发生这种情况?我们使用的是 Python 3.2。
相关的:
我有一个基本类型 ( tp_new
and tp_dealloc
),然后我在运行时创建派生类型。派生类型具有字典tp_base
、tp_getattro
和tp_setattro
。
这就是函数绑定到 Python 类/类型的方式:
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);
其中 funcName 和 className 是 const char*。pythonFunc 是一个通用的 Python 函数,它处理调用绑定到我们的元系统的所有函数。classObj 是指向具有成员 m_pyClassType(PyTypeObject 的类型)的 PythonClass 的指针。
PyGeneralObj
是一个新对象,有两个 const char* 和一个 void*(这是 C++ 中的对象)
我这样做PyType_Ready
并且没有错误,然后增加我的类型。然后我将对象添加到我从PyImport_ImportModule
. 我确实将我的主模块附加到运行时并初始化 python 并导入我的模块。
如果需要更多信息/代码,我可以发布更多信息。我希望这是有道理的,这是我第一次在 stackoverflow 上发帖。
为澄清起见,我们希望拥有在 C++ 端完全解析的动态属性。对于函数,我希望能够覆盖PyObject* self
参数,以便我可以获得需要调用的函数的字符串名称。
我们不想使用 Boost、Cython 等第三方库/接口。