如何在pythoncapi中定义类方法?

2024-09-27 19:10:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用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();
};

输出是

^{pr2}$

Module函数的调用没有任何问题,但是类方法在没有适当的输入变量的情况下被调用。在


Tags: pynonenewincludemyclassargsstaticstart
1条回答
网友
1楼 · 发布于 2024-09-27 19:10:32

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

从Python2.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;
};

结果

^{pr2}$

注意,我打印了self的指针值,它是NULL。 我还补充道

if(PyErr_Occurred())
    PyErr_Print();

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

相关问题 更多 >

    热门问题