Этот ответ на вопрос, который вы связали с , кажется, вам нужен. inspect.getargspec
делает именно то, что вы хотите на стороне Python, и, как говорится в ответе, вы можете использовать PyObject_CallMethod или одну из связанных функций, описанных в этой цели ссылки, для вызова inspect.getargspec
из вашего кода C ++, получить возвращенный кортеж как 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)
<ч />
Вот пример того, что вы должны сделать (не все возможные ошибки могут быть проверены, но это должны быть все проверки 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
}
}
}
}
}