从C ++查找python函数参数 [英] Finding python function parameters from C++
问题描述
我正在从C ++调用python函数.我想知道是否有可能确定参数的数量和这些参数的名称.我已阅读链接如何从C查找Python函数的参数数量?但是我不太了解.
I am calling python functions from C++. I was wondering if it is possible to determine the number of parameters and the names of these parameters. I have read the link How to find the number of parameters to a Python function from C? however I do not really understand.
我有这个C ++函数,它从pyFunction.py调用函数"add". "add"带有两个参数并返回总和.
I have this C++ function that calls the function 'add' from pyFunction.py. 'add' takes two parameters and returns the sum.
static float CallPythonFunc( float *parameters )
{
PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pArgs;
float ret;
// Initialize the python interpreter
Py_Initialize();
// Make sure we are getting the module from the correct place
// ### This is where we will put the path input
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\"/Developer/IsadoraSDK/IsadoraDemoMathFunction/\")");
// Build the name object
// ### This is where we will put the function input
pName = PyString_FromString("pyFunction");
// Load the module object
pModule = PyImport_Import(pName);
// pDict is a borrowed reference
pDict = PyModule_GetDict(pModule);
// pFunc is a borrowed reference
pFunc = PyDict_GetItemString(pDict, "add");
//
// Somehow get the number of arguments and possible the arguments names from 'add'
//
if (PyCallable_Check(pFunc))
{
// Set the number of arguments
// This is where I would like to pass in number of arguments
pArgs = PyTuple_New( 2 /*number of arguments*/ );
//
// Instead of the following if I had the arguments I could loop through them
// and pass the correct number in
//
// Argument 1
pValue = PyFloat_FromDouble((double)parameters[0]);
PyTuple_SetItem(pArgs, 0, pValue);
// Argument 2
pValue = PyFloat_FromDouble((double)parameters[1]);
PyTuple_SetItem(pArgs, 1, pValue);
// Make the call to the function
pValue = PyObject_CallObject(pFunc, pArgs);
// Set return value
ret = (float)PyFloat_AsDouble(pValue);
// Clean up
Py_DECREF(pArgs);
Py_DECREF(pValue);
}
// Clean up
Py_DECREF(pModule);
Py_DECREF(pName);
// Finish the Python Interpreter
Py_Finalize();
return ret;
}
我对C/C ++确实不那么熟悉,所以任何帮助都将非常有帮助.感谢大家的宝贵时间!
I am really not that familiar with C/C++ so any help would be really helpful. Thanks to everyone for their time!
像下面这样吗?
PyObject *tuple, *arglist;
tuple = PyObject_CallMethod(pFunc,"inspect.getargspec","add");
arglist = PyTuple_GetItem(tuple,0);
int size = PyObject_Size(arglist);
推荐答案
PyObject_CallMethod 或在该链接目标处描述的相关函数之一,以从C ++代码中调用inspect.getargspec
,将返回的元组作为PyObject
获取,并使用PyTuple_GetItem(returned_tuple, 0)
获取参数列表,然后在列表上使用PyObject_Size()
或PyObject_Length()
获取参数数量.您还需要检查返回的元组的第二个和第三个元素,并对不是Py_None
的两个参数中的每一个,将参数数目增加1.有关原因,请参见下面的代码段.
This answer to the question you linked to seems to be what you want. inspect.getargspec
does exactly what you want on the Python side, and as the answer states, you can use PyObject_CallMethod or one of the related functions described at that link target to call inspect.getargspec
from your C++ code, get the returned tuple as a PyObject
, use PyTuple_GetItem(returned_tuple, 0)
to get the argument list, and then use either PyObject_Size()
or PyObject_Length()
on the list to get the number of arguments. You'll also want to check the second and third elements of the returned tuple and increment the number of arguments by 1 for each of the two that is not Py_None
. See the below code snippet for why.
>>> import inspect
>>> def testfunc(a, b, c, *d, **e):
pass
>>> inspect.getargspec(testfunc)
ArgSpec(args=['a', 'b', 'c'], varargs='d', keywords='e', defaults=None)
这是您应该执行的操作的示例(并非可以检查所有可能的错误,但是应该是所有必要的NULL检查):
Here's an example of what you should do (not all possible errors may be checked for, but it should be all of the NULL checks that may be necessary):
PyObject *pName, *pInspect, *argspec_tuple, *arglist;
int size;
pName = PyString_FromString("inspect");
if (pName)
{
pInspect = PyImport_Import(pName);
Py_DECREF(pName);
if (pInspect)
{
pName = PyString_FromString("getargspec");
if (pName)
{
argspec_tuple = PyObject_CallMethodObjArgs(pInspect, pName, pFunc, NULL);
Py_DECREF(pName);
if (argspec_tuple)
{
arglist = PyTuple_GetItem(argspec_tuple, 0);
if (arglist)
{
size = PyObject_Size(arglist)
+ (PyTuple_GetItem(argspec_tuple, 1) == Py_None ? 0 : 1)
+ (PyTuple_GetItem(argspec_tuple, 2) == Py_None ? 0 : 1); // Haven't actually tested this, but it should work
}
}
}
}
}
这篇关于从C ++查找python函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!