如何将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,例如,因为您返回了它并将所有权传递给了不知道它是借用引用的调用方).否决投票的原因?WillPyObject*b=Py\u RETURN\u TRUE;
甚至可以编译吗?@MadPhysicast:可能不会,但我不会让编译器在非严格模式下运行时发出警告。:-)这不是很好的建议,也不会解决OP方法中的一些主要问题。
Py_INCREF(b);