[英]What is the “correct” way to pass a boolean to a Python C extension?
This is a simple example from the python documentation (http://docs.python.org/extending/extending.html): 这是python文档(http://docs.python.org/extending/extending.html)中的一个简单示例:
static PyObject *
spam_system(PyObject *self, PyObject *args)
{
const char *command;
int sts;
if (!PyArg_ParseTuple(args, "s", &command))
return NULL;
sts = system(command);
return Py_BuildValue("i", sts);
}
If I want to pass an additional boolean parameter to the function - what's the "correct" way to do it? 如果我想将另一个布尔参数传递给函数 - 这是什么“正确”的方法呢?
There doesn't seem to be a bool option to pass to PyArg_ParseTuple(). 似乎没有传递给PyArg_ParseTuple()的bool选项。 So I thought of the following:
所以我想到了以下几点:
Any of these preferable? 这些中哪一个更好? Other options?
其他选择?
4 maybe there's a way to get any type of variable and get its truth value (ie an empty array will is falsy etc.) which is what python function usually do.
4也许有一种方法可以获得任何类型的变量并获得其真值(即空数组将是假数据等),这是python函数通常所做的。
Yes: (from Python/C API Reference ) 是的:(来自Python / C API参考 )
int PyObject_IsTrue(PyObject *o)
Returns 1 if the object o is considered to be true, and 0 otherwise.
如果对象o被认为是真,则返回1,否则返回0。 This is equivalent to the Python expression not not o.
这相当于Python表达式而不是o。 On failure, return -1.
失败时,返回-1。
EDIT. 编辑。 To answer the actual question, I think approach 1 is correct, because int really is the corresponding type in C. Approach 4 is good, but if you document your function as taking a bool, you are not obligated to accept just any object.
为了回答实际问题,我认为方法1是正确的,因为int实际上是C中的相应类型。方法4很好,但如果你将你的函数记录为bool,你没有义务接受任何对象。 Explicit type checks as in 3 without a reason are frowned upon in Python.
在Python中,没有理由的显式类型检查在3中是不受欢迎的。 Conversion to another Python object as in 2 does not help your C code.
像2中一样转换为另一个Python对象对您的C代码没有帮助。
Currently, parsing an integer (as "i"
) is the accepted way to take a bool. 目前,解析整数(作为
"i"
)是获取bool的可接受方式。
From Python 3.3, PyArg_ParseTuple
will accept "p"
(for "predicate"), per the latest NEWS : 根据Python 3.3,
PyArg_ParseTuple
将接受"p"
(对于“谓词”),根据最新消息 :
- Issue #14705 : The PyArg_Parse() family of functions now support the 'p' format unit, which accepts a "boolean predicate" argument.
问题#14705 :PyArg_Parse()系列函数现在支持'p'格式单元,它接受“布尔谓词”参数。 It converts any Python value into an integer--0 if it is "false", and 1 otherwise.
它将任何Python值转换为整数 - 如果为“false”则为0,否则为1。
Note that when using PyArg_ParseTuple
with "p"
, the argument must be a (pointer to) int
, not the C99 bool
type: 注意,当使用带有
"p"
PyArg_ParseTuple
时,参数必须是(指向) int
指针,而不是C99 bool
类型:
int x; // not "bool x"
PyArg_ParseTuple(args, kwds, "p", &x);
I have found another approach: 我找到了另一种方法:
PyObject* py_expectArgs;
bool expectArgs;
PyArg_ParseTupleAndKeywords(args, keywds, (char *)"O!", (char **)kwlist, &PyBool_Type, &py_expectArgs);
expectArgs = PyObject_IsTrue(py_expectArgs);
In case of wrong param call there is "auto" exception "argument 1 must be bool, not int" 如果错误的参数调用有“自动”异常“参数1必须是bool,而不是int”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.