python - 如何在python C-api中解析所需的互斥参数
问题描述
如何使用 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()
导致第二次调用失败(输出 python 错误是:TypeError:需要浮点数)。
我知道可以使用argparse
python 模块解决上述问题,但更喜欢直接使用 C-api 的解决方案。这里的一个想法是,如果有可能首先将输入复制 到args
两个kwargs
新PyObject
变量中,然后在第二次调用PyArg_ParseTupleAndKeywords()
如何释放为此分配的内存)。
解决方案
似乎问题在于第一次调用PyArg_ParseTupleAndKeywords()
设置错误指示器导致第二次调用函数失败。所以解决方案是在对 的调用PyErr_Clear()
之间插入一个调用PyArg_ParseTupleAndKeywords()
。总之,以下代码执行任务
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))) {
PyErr_Clear();
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
if (b==0 && c==0) {
PyErr_SetString(PyExc_TypeError,"Required mutually exclusive arguments 'b' or 'c' (pos 2) not found (or input with value 0)");
return NULL;
} else if (b!=0 && c!=0) {
PyErr_SetString(PyExc_TypeError,"Use of multiple mutually exclusive required arguments 'b' and 'c' (pos 2)");
return NULL;
}
...
}
再一次,这并不能防止使用两个参数调用函数,b
并且c
假设其中一个是 0 而另一个不是。然而,这是一个小问题。
推荐阅读
- sql - 如何在变量中设置哈希?
- c++ - 动态创建在 C++ 中完美转发的函数参数
- python - python在if语句中超出索引
- c# - 如何避免带有重复控制器名称的 AmbiguousMatchException
- visual-studio-code - 如何从 vscode 中的全局 launch.json 中删除配置
- r - 带有 facet_wrap 的数学符号无法正确显示
- c# - 在 C# 中正确使用 VB 的 GetObject
- sabre - API 令牌:如何访问 Sabre SOAP API?
- .net-core - 使用 Projections 不会加载使用数据加载器解析的字段
- xamarin.forms - Xamarin 表单 PropertyChanged 对象为空