向Python C扩展传递布尔值的“正确”方法是什么?

2024-05-23 20:01:06 发布

您现在位置:Python中文网/ 问答频道 /正文

这是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);
}

如果我想向函数传递一个额外的布尔参数,那么“正确”的方法是什么?

似乎没有bool选项可以传递给PyArg_ParseTuple()。所以我想到了以下几点:

  1. 读取一个整数并使用该值(因为bool是int的一个子类)
  2. 对整数调用PyBool_FromLong()
  3. 读取和对象并调用PyBool_Check()来验证它是否为bool
  4. 也许有一种方法可以得到任何类型的变量并得到它的真值(即空数组将是falsy等),这就是python函数通常做的事情。

有什么更好的吗?其他选择?


Tags: 方法函数returnargs整数systemcommandint
3条回答

目前,解析整数(如"i")是接受bool的公认方法。

从Python 3.3中,PyArg_ParseTuple将接受"p"(对于“谓词”),每the latest NEWS

  • Issue #14705: The PyArg_Parse() family of functions now support the 'p' format unit, which accepts a "boolean predicate" argument. It converts any Python value into an integer--0 if it is "false", and 1 otherwise.

注意,与"p"一起使用PyArg_ParseTuple时,参数必须是(指向)int的指针,而不是C99bool类型:

int x;    // not "bool x"
PyArg_ParseTuple(args, kwds, "p", &x);

我找到了另一种方法:

PyObject* py_expectArgs;
bool expectArgs;

PyArg_ParseTupleAndKeywords(args, keywds, (char *)"O!", (char **)kwlist, &PyBool_Type, &py_expectArgs);

expectArgs = PyObject_IsTrue(py_expectArgs);

如果参数调用错误,则存在“auto”异常“参数1必须是bool,而不是int”

4 maybe there's a way to get any type of variable and get its truth value (i.e an empty array will is falsy etc.) which is what python function usually do.

是:(来自Python/C API Reference

int PyObject_IsTrue(PyObject *o)

Returns 1 if the object o is considered to be true, and 0 otherwise. This is equivalent to the Python expression not not o. On failure, return -1.

编辑。为了回答实际的问题,我认为方法1是正确的,因为int实际上是C中的对应类型。方法4是好的,但是如果您将您的函数记录为使用bool,您就没有义务只接受任何对象。在Python中,没有理由的显式类型检查与3中一样不受欢迎。像2中那样转换到另一个Python对象对C代码没有帮助。

相关问题 更多 >