从C++; 我从C++调用Python函数。我想知道是否有可能确定参数的数量和这些参数的名称。我已经阅读了链接,但我并不真正理解 我有一个C++函数,它调用函数从PyFrasy.Py中添加。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; }
我对C/C++真的不太熟悉,所以任何帮助都会非常有用。谢谢大家的时间 编辑: 那么像下面这样的事情从C++; 我从C++调用Python函数。我想知道是否有可能确定参数的数量和这些参数的名称。我已经阅读了链接,但我并不真正理解 我有一个C++函数,它调用函数从PyFrasy.Py中添加。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; },c++,python,parameters,C++,Python,Parameters,我对C/C++真的不太熟悉,所以任何帮助都会非常有用。谢谢大家的时间 编辑: 那么像下面这样的事情 PyObject *tuple, *arglist; tuple = PyObject_CallMethod(pFunc,"inspect.getargspec","add"); arglist = PyTuple_GetItem(tuple,0); int size = PyObject_Size(arglist); 似乎是你想要的检查。GETARSPECU< /COD>在Python端确实需
PyObject *tuple, *arglist;
tuple = PyObject_CallMethod(pFunc,"inspect.getargspec","add");
arglist = PyTuple_GetItem(tuple,0);
int size = PyObject_Size(arglist);
似乎是你想要的<代码>检查。GETARSPECU< /COD>在Python端确实需要什么,并且当回答状态时,您可以使用或链接在该链接目标上描述的相关函数之一调用C++代码中的“代码>检查。GEGARSPECU</代码>,将返回的元组作为<代码> pyObjult<代码>,使用<代码> PyTutPulgGestEM(ReTurndEdtuple,0)获取参数列表,然后在列表上使用PyObject\u Size()
或PyObject\u Length()
获取参数数量。您还需要检查返回的元组的第二个和第三个元素,并将非Py\u None
的两个元素的参数数量分别增加1。请参阅下面的代码片段了解原因
>>> import inspect
>>> def testfunc(a, b, c, *d, **e):
pass
>>> inspect.getargspec(testfunc)
ArgSpec(args=['a', 'b', 'c'], varargs='d', keywords='e', defaults=None)
下面是一个您应该做的示例(并非所有可能的错误都可以检查,但应该是所有可能需要的空检查):
谢谢你的回复。我还为后续问题编辑了我的帖子,除了你在编辑中添加的内容之外,你还想添加一些类似于
size+=(PyTuple\u GetItem(tuple,1)==Py\u None?0:1)+(PyTuple\u GetItem(tuple,2)==Py une?0:1)
来解释*
和**
参数的可能性。(如果您不认识所使用的语法,它被称为三元运算符,类似于一个内嵌的If…else
语句。)哦,实际上,检查我的更新答案,了解您可能想要做什么。哦,刚才还注意到,在Python 3+中,您希望使用getfullargspec
,而不是getargspec
,因为后者自3.0版以来已被弃用。由于getfullargspec
返回的元组的起始元素与getargspec
返回的元组的元素相同,因此此处的语法不会更改,但如果Python函数只有关键字参数或注释,这一点尤为重要,asgetargspec
用于具有此功能的函数时失败。这也意味着您需要像检查普通参数列表的大小一样检查此类参数。
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
}
}
}
}
}