Как можно разобрать группу обязательных, но взаимоисключающих аргументов с помощью Python C-api?
например. с учетом определения функции
static PyObject* my_func(PyObject *self, PyObject *args, PyObject *kwargs) {
double a; // first argument, required
double b=0, c=0; // second argument, required but mutually exclusive, b is default keyword if no keyword is set
char d[] = "..."; // third argument, optional
// parse arguments
...
}
Моя идея заключалась в том, чтобы дважды проанализировать входные аргументы, то есть заменить ...
выше на:
static const char *kwList1[] = {"a","b","c","d"};
static const char *kwList2[] = {"a","b","d"};
int ret;
if (!(ret = PyArg_ParseTupleAndKeywords(args,kwargs,"d|dds",(char **)kwList1,&a,&b,&c,&d))) {
ret = PyArg_ParseTupleAndKeywords(args,kwargs,"d|ds",(char **)kwList2,&a,&b,&d));
}
if (!ret) return NULL;
// verify that one of, but not both, variables b and c are non-zero
...
Однако второй вызов PyArg_ParseTupleAndKeywords()
возвращает 0 для правильного ввода, поэтому я предполагаю, что переменные args
и kwargs
имеют некоторые атрибуты, установленные при первом вызове PyArg_ParseTupleAndKeywords()
, что приводит к сбою второго вызова (ошибка выходного питона: TypeError: требуется плавающее число).
Я знаю, что вышесказанное можно решить с помощью модуля argparse
python, но я бы предпочел решение, использующее C-api. Одна из идей здесь была бы, если бы можно было сначала скопировать входные данные args
и kwargs
в две новые переменные PyObject
и использовать их во втором вызове PyArg_ParseTupleAndKeywords()
, однако я не могу найти какой-либо Функция для этого (думаю, мне также нужно знать, как освободить память, выделенную для этого).