【发布时间】:2017-07-09 01:41:53
【问题描述】:
假设我有一个人为的函数,如下所示:
静态 int foo(PyObject *self, PyObject *args) { 字符 *a = ""; 字符 *b = ""; 诠释 c = 0; if (!PyArg_ParseTuple(args, "ss|i", &a, &b, &c) { 返回空值; } printf("c 是 %i\n", c); //some_function_requiring_int_data_type(c); }我希望用户能够提交int 或None 作为c arg 的值,但上面的代码不允许这样做:
>>>from spam import foo
>>>foo('a', 'b')
c is 0
>>>foo('a', 'b', 100)
c is 100
>>>foo('a', 'b', None)
TypeError: an integer is required
目前,为了启用这种行为,我有一堆丑陋的代码,如下所示:
静态 int foo(PyObject *self, PyObject *args) { 字符 *a = ""; 字符 *b = ""; PyObject *c = NULL; // 注意我如何使用 PyObject * 诠释 c_int = 0; // 注意我有一个伴随的 int if (!PyArg_ParseTuple(args, "ss|O", &a, &b, &c) { 返回空值; } // 丑陋的代码从这里开始 如果 (c) { 如果(c!= Py_None){ 如果(!PyInt_Check(c)){ PyErr_SetString(PyExc_TypeError, "c 必须是 int 或 None"); 返回; } c_int = PyInt_AsSize_t(c); } } printf("c_int 是 %i\n", c_int); //some_function_requiring_int_data_type(c_int); }及其用途:
>>>from spam import foo
>>>foo('a', 'b')
c is 0
>>>foo('a', 'b', 100)
c is 100
>>>foo('a', 'b', None)
c is 0
【问题讨论】:
-
如果可能的话,我会将其作为仅关键字参数(那么就无需将
None作为占位符值传递)。失败我会使用“O&”和转换器功能。这也有很多丑陋的代码,但它至少在一个清晰的独立单元中。 (如果有帮助,我可以发布代码,但应该很容易弄清楚)。不幸的是,使用 C api 很难完全避免丑陋的代码。 -
@DavidW 感谢
converter function的提示。请您查看我的答案 - 我对此有一些担忧。此外,您是否愿意发布您的建议以使用仅关键字参数作为答案? -
我已经发布了我的转换器功能版本。与您的主要区别在于它不会更改
None上的任何内容或错误,因此可以由调用者设置默认值。除非我遗漏了什么,否则我认为您的不应该出现段错误。稍后我将尝试添加仅关键字示例... -
... 并且只添加了关键字示例,我认为这不太难看。
标签: python python-2.7 python-c-api