gpt4 book ai didi

python - 如何在 Python C API 中定义类方法?

转载 作者:太空宇宙 更新时间:2023-11-03 23:47:36 25 4
gpt4 key购买 nike

我试图在 C++ 代码中创建一个 Python 类定义并在 Python 中访问它。然而,函数被调用但参数没有被正确接收。请帮助我正确地执行此操作。

#include <iostream>
#include <Python.h>

using namespace std;

#include <Python.h>

static PyObject* MyClass__Init(PyObject *self, PyObject *args)
{
cout << "MyClass__Init Called" << endl;
Py_INCREF(Py_None);
return Py_None;
};

static PyObject* MyModule__Start(PyObject *self, PyObject *args)
{
const char* zBuff;

if (PyArg_ParseTuple(args, "s", &zBuff))
cout << "MyModule Start Called with parameter " << zBuff << endl;
else
cout << "MyModule Start ERROR" << endl;

Py_INCREF(Py_None);
return Py_None;
};

static PyObject* MyClass__Start(PyObject *self, PyObject *args)
{
const char* zBuff;

if (PyArg_ParseTuple(args, "s", &zBuff))
cout << "MyClass Start Called with parameter" << zBuff << endl;
else
cout << "MyClass Start ERROR" << endl;

Py_INCREF(Py_None);
return Py_None;
};

static PyMethodDef pModuleMethods[] =
{
{"Start", MyModule__Start, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};

static PyMethodDef pClassMethods[] =
{
{"__init__", MyClass__Init, METH_VARARGS, ""},
{"Start", MyClass__Start, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};

void Start()
{
Py_Initialize();

/* create a new module and class */
PyObject *pClassDic = PyDict_New();
PyObject *pClassName = PyString_FromString("MyClass");
PyObject *pClass = PyClass_New(NULL, pClassDic, pClassName);

PyObject *pModule = Py_InitModule("MyModule", pModuleMethods);
PyObject *pModuleDic = PyModule_GetDict(pModule);

/* add methods to class */
for (PyMethodDef* pDef = pClassMethods; pDef->ml_name != NULL; pDef++)
{
PyObject *pFunc = PyCFunction_New(pDef, NULL);
PyObject *pMethod = PyMethod_New(pFunc, NULL, pClass);
PyDict_SetItemString(pClassDic, pDef->ml_name, pMethod);
}

PyDict_SetItemString(pModuleDic, "MyClass", pClass);

PyRun_SimpleString("import MyModule\n"
"MyModule.Start('Hello Module')\n"
"myObj = MyModule.MyClass()\n"
"myObj.Start('Hello Class')\n");

Py_Finalize();
};

int main()
{
Start();
};

输出是,

MyModule Start Called with parameter Hello Module
MyClass__Init Called
MyClass Start ERROR

模块函数调用没有任何问题,但类方法调用时没有正确的输入变量。

最佳答案

似乎 self 的参数总是 NULL 并且相反 - 对于类方法 - 对 self 的引用在参数列表中传递。因此,要解析类方法的参数,您还需要解析对 self 的引用。

从 Python 2.6 开始,您可以向 PyArg_ParseTuple 提供格式说明符列表。格式说明符的数量必须适合传递给函数的参数数量(参见 (items) (tuple) [matching-items] 下的 https://docs.python.org/2/c-api/arg.html)。

通过修改您的 MyClass__Start 函数来解析附加参数,您可以解析并打印两个参数以检查它们。对我来说,下面的代码

static PyObject* MyClass__Start(PyObject *self, PyObject *args)
{
PyObject* argListSelf;
const char* zBuff;

if (PyArg_ParseTuple(args, "Os", &argListSelf, &zBuff)) {
cout << "MyClass Start Called with parameters " <<
cout << PyString_AsString(PyObject_Str(argListSelf)) <<
cout << " and " << zBuff << endl;

cout << "self " << PyString_AsString(PyObject_Str(self)) << endl;
}
else {
if(PyErr_Occurred())
PyErr_Print();

cout << "MyClass Start ERROR" << endl;
}

Py_INCREF(Py_None);
return Py_None;
};

结果

MyModule Start Called with parameter Hello Module
MyClass__Init Called
MyClass Start Called with parameters \
0x602428<?.MyClass instance at 0x7f484a333200>0x602428 and HelloClass
self <NULL>

请注意,我打印了 self 的指针值,它是 NULL。我也加了

if(PyErr_Occurred())
PyErr_Print();

为了调试目的,我总是会添加它。

关于python - 如何在 Python C API 中定义类方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29277027/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com