kon*_*nwa 4 c++ python parameters
我正在从 C++ 调用 python 函数。我想知道是否可以确定参数的数量和这些参数的名称。我已阅读链接How to find the number of parameters to a Python function from C? 但是我真的不明白。
我有这个 C++ 函数,它从 pyFunction.py 调用函数“add”。'add' 接受两个参数并返回总和。
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;
}
Run Code Online (Sandbox Code Playgroud)
我真的不太熟悉 C/C++,所以任何帮助都会非常有帮助。感谢大家的时间!
编辑:所以像下面这样?
PyObject *tuple, *arglist;
tuple = PyObject_CallMethod(pFunc,"inspect.getargspec","add");
arglist = PyTuple_GetItem(tuple,0);
int size = PyObject_Size(arglist);
Run Code Online (Sandbox Code Playgroud)
您链接到的问题的这个答案似乎是您想要的。inspect.getargspec在 Python 方面完全按照您的要求执行操作,正如答案所述,您可以使用PyObject_CallMethod或该链接目标中描述的相关函数之一inspect.getargspec从您的 C++ 代码中调用,将返回的元组作为 a获取PyObject,用于PyTuple_GetItem(returned_tuple, 0)获取参数列表,然后使用列表中的PyObject_Size()或PyObject_Length()来获取参数的数量。您还需要检查返回的元组的第二个和第三个元素,并为不是 的两个元素中的每一个将参数数量增加 1 Py_None。请参阅下面的代码片段了解原因。
>>> import inspect
>>> def testfunc(a, b, c, *d, **e):
pass
>>> inspect.getargspec(testfunc)
ArgSpec(args=['a', 'b', 'c'], varargs='d', keywords='e', defaults=None)
Run Code Online (Sandbox Code Playgroud)
这是您应该做什么的示例(并非所有可能的错误都可能被检查,但应该是所有可能需要的 NULL 检查):
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
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)