Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将Python布尔对象转换为C int(或C+;+;布尔)(Python C API)_Python_C_Python C Api - Fatal编程技术网

如何将Python布尔对象转换为C int(或C+;+;布尔)(Python C API)

如何将Python布尔对象转换为C int(或C+;+;布尔)(Python C API),python,c,python-c-api,Python,C,Python C Api,我有一个变量PyObject,我知道它是一个Python bool。它可以是True或False(例如Py\u-True或Py\u-False)。现在我想把它转换成C++。 对字符串执行此操作并不难,有一个帮助函数-PyBytes\u AsString可以将python字符串转换为C字符串。现在我需要类似于boolean的东西(或者int,因为C中没有bool) 或者,如果没有转换,可能有一些函数可以与true或false进行比较?类似于intpybool\u IsTrue(PyObject*)

我有一个变量
PyObject
,我知道它是一个Python bool。它可以是
True
False
(例如
Py\u-True
Py\u-False
)。现在我想把它转换成C++。 对字符串执行此操作并不难,有一个帮助函数-
PyBytes\u AsString
可以将python字符串转换为C字符串。现在我需要类似于boolean的东西(或者int,因为C中没有
bool

或者,如果没有转换,可能有一些函数可以与true或false进行比较?类似于
intpybool\u IsTrue(PyObject*)

以下是一些示例代码,以便于理解我需要的内容:

#include <Python.h>

int main()
{
    /* here I create Python boolean with value of True */
    PyObject *b = Py_RETURN_TRUE;
    /* now that I have it I would like to turn in into C type so that I can determine if it's True or False */
    /* something like */
    if (PyBool_IsTrue(b))
    { /* it's true! */ }
    else
    { /* it's false */ }
    return 0;
}

答案在Python标题中,但可能并不明显

Python头在这里声明了2个有点静态的对象,带有两个宏:

/* Don't use these directly */
PyAPI_DATA(struct _longobject) _Py_FalseStruct, _Py_TrueStruct;

/* Use these macros */
#define Py_False ((PyObject *) &_Py_FalseStruct)
#define Py_True ((PyObject *) &_Py_TrueStruct)

/* Macros for returning Py_True or Py_False, respectively */
#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
似乎
True
False
实际上都是Python对象,Python中
True
False
的所有值实际上都是对这两个全局
Py_True
Py_False
对象的引用。当使用
Py\u RETURN\u TRUE
返回此类对象时,引用计数将递增

这意味着,每个指向PyObject的C指针的值
Py_True
实际上都指向相同的内存地址。因此,检查
PyObject
是否为true或false非常简单:

/* here I create Python boolean with value of True */
PyObject *b = Py_True;
Py_INCREF(b);
/* now we compare the address of pointer with address of Py_True */
if (b == Py_True)
{ /* it's true! */ }
else
{ /* it's false */ }
通常最好使用
int-PyBool\u检查(PyObject*)
来验证所讨论的对象是否是Python布尔值。

每个Python对象都可以使用它的真实性进行评估,并且您应该优先使用它来指导
PyTrue
/
PyFalse
单例检查,除非您绝对知道,该对象是一个
PyBool

用途是:

int truthy = PyObject_IsTrue(someobj);
if (truthy == -1) return APPROPRIATEERRORRETURN;

if (truthy)
{ /* it's true! */ }
else
{ /* it's false */ }
如果您知道它肯定是一个bool,您可以只测试
someobj==Py\u True
,或者使用它将任何逻辑整数类型(任何实现
\uuu index\uuu
的东西,
bool
int
的子类,因此它在逻辑上也是一个整数)转换为有符号的
size\u t
值(如果
\uuuu index\uuuu
返回的数字与已签名的
大小\u t
不符,则返回-1并设置异常)

一般来说,不做
someobj==Py_-True
的原因是,如果someobj是真的,就像在Python层做
:如果
someobj
1
,或者是非空的
str
,当Python代码很少关心
True
false
时,它会被视为false,但是相反,“真实”和“虚假”

此外,这:

PyObject *b = Py_RETURN_TRUE;
是完全错误的。这将递增并返回它;后续代码都不会执行。您希望:

PyObject *b = Py_True;
对于借用的引用,添加后续引用:

Py_INCREF(b);

如果您打算稍后返回它,则将其设置为自有引用(因为它是一个不会消失的单例引用,使用借用引用是可以的,除非您知道它将在以后被
DECREF
ed,例如,因为您返回了它并将所有权传递给了不知道它是借用引用的调用方).

否决投票的原因?Will
PyObject*b=Py\u RETURN\u TRUE;
甚至可以编译吗?@MadPhysicast:可能不会,但我不会让编译器在非严格模式下运行时发出警告。:-)这不是很好的建议,也不会解决OP方法中的一些主要问题。
Py_INCREF(b);