25

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

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

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

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

这些中的任何一个更可取吗?其他选择?

4

3 回答 3

23

4也许有一种方法可以获取任何类型的变量并获取其真值(即空数组将是假的等),这就是python函数通常所做的。

是:(来自Python/C API 参考

int PyObject_IsTrue(PyObject *o)

如果对象 o 被认为为真,则返回 1,否则返回 0。这相当于 Python 表达式 not not o。失败时,返回-1。

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

于 2012-02-16T17:52:53.433 回答
17

目前,解析整数 (as "i") 是接受布尔值的方式。

根据最新的 NEWS ,从 Python 3.3 开始,PyArg_ParseTuple将接受"p"(对于“谓词”):

  • 问题 #14705:PyArg_Parse() 系列函数现在支持“p”格式单元,它接受“布尔谓词”参数。它将任何 Python 值转换为整数——如果为“假”则为 0,否则为 1。

请注意,使用PyArg_ParseTuplewith时"p",参数必须是 (pointer to) int,而不是 C99bool类型:

int x;    // not "bool x"
PyArg_ParseTuple(args, kwds, "p", &x);
于 2012-05-22T11:01:48.947 回答
7

我找到了另一种方法:

PyObject* py_expectArgs;
bool expectArgs;

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

expectArgs = PyObject_IsTrue(py_expectArgs);

如果参数调用错误,则会出现“auto”异常“argument 1 must be bool, not int”

于 2013-09-16T11:45:41.617 回答