使用关键字参数的PyObject_CallMethod函数

9

我正在尝试将Python(2.7)库嵌入到我的C应用程序中,并使用Python/C API从C中调用Python代码。我需要调用一个带有关键字参数的Python方法。语义上,我正在尝试实现以下Python代码行的等效操作:

myobject.dosomething('blahdy blah', somearg=True)

通过阅读文档,我已经完成了以下代码,但是没有传入关键字参数:

PyObject_CallMethod(myobject, "dosomething", "s", "blahdy blah");

我对Python并不是非常熟悉,在这一点上遇到了困难,因为文档并不是很清晰,谷歌搜索也没有找到太多有用的信息。我会非常感激任何帮助。


2
似乎没有一个函数可以使用关键字参数调用方法。至少在这里看起来是这样的:http://mail.python.org/pipermail/python-dev/2007-June/073661.html。然而,`PyObject_Call`总是有效的。 - Bakuriu
@Bakuriu:感谢你的提示!最终,那正是我最终所做的。 - Tamas Czinege
2个回答

9
Tamas的答案可以完成工作,但也会泄漏内存。为避免泄漏,请使用:
PyObject *args = Py_BuildValue("(s)", "blahdy blah");    
PyObject *keywords = PyDict_New();
PyDict_SetItemString(keywords, "somearg", Py_True);
PyObject *myobject_method = PyObject_GetAttrString(myobject, "do something");

PyObject *result = PyObject_Call(myobject_method, args, keywords);
Py_DECREF(args);
Py_DECREF(keywords);
Py_DECREF(myobject_method);

// Do something with the result

Py_DECREF(result);

当然,如果Python代码中存在任何错误或异常,一些PyObjects可能为空,这将导致您的程序崩溃。检查空结果和/或使用Py_DECREFX()可以帮助您避免这种情况。

请注意,如果您没有参数,但只想传递关键字参数,例如调用 pd.to_json(orient="table"),则不能将 null 传递给 args,而是要创建一个空元组 PyObject *args = PyTuple_New(0); 并将其作为第二个参数传递给 PyObject_Call - MyDeveloperDay

8

最后我使用PyObject_Call来完成此操作(感谢Bakuriu的提示!)。如果有人想知道如何做到这一点,这是我的代码:

PyObject *args = Py_BuildValue("(s)", "blahdy blah");    
PyObject *keywords = PyDict_New();
PyDict_SetItemString(keywords, "somearg", Py_True);

PyObject_Call(PyObject_GetAttrString(myobject, "do something"), args, keywords);
Py_DECREF(args);
Py_DECREF(keywords);

1
这里存在内存泄漏问题。PyObject_GetAttrString 返回一个新的引用,因此我们需要在调用属性完成后调用 Py_DECREF - Tirth Patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接