我有一个变量PyObject
,我知道它是一个Python bool。它可以是True
或False
(例如Py_True
或Py_False
)。现在我想以某种方式将其转换为C ++。
使用字符串执行此操作并不困难,有一个辅助函数 - PyBytes_AsString
将python字符串转换为C字符串。现在我需要像boolean那样的东西(或者因为C中没有bool
而是int。)
或者如果没有转换,也许某些功能可以与true或false进行比较?像int PyBool_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;
}
这显然不起作用,因为没有像PyBool_IsTrue
这样的功能:(我该怎么做?
Python标题的片段(boolobject.h):
/* Boolean object interface */
#ifndef Py_BOOLOBJECT_H
#define Py_BOOLOBJECT_H
#ifdef __cplusplus
extern "C" {
#endif
PyAPI_DATA(PyTypeObject) PyBool_Type;
#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type)
/* Py_False and Py_True are the only two bools in existence.
Don't forget to apply Py_INCREF() when returning either!!! */
/* 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
/* Function to return a bool from a C long */
PyAPI_FUNC(PyObject *) PyBool_FromLong(long);
#ifdef __cplusplus
}
#endif
#endif /* !Py_BOOLOBJECT_H */
答案 0 :(得分:7)
每个 Python对象都可以使用PyObject_IsTrue
评估其真实性,您应优先使用它来指导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_True
,或者使用PyNumber_AsSsize_t
来转换任何逻辑整数类型(任何实现__index__
的内容,而bool
是一个int
的子类,因此它在逻辑上也是一个整数)到签名的size_t
值(如果__index__
返回的数字不符合签名的size_t
,它将返回-1,异常设置)。
一般不做someobj == Py_True
的原因是因为它就像在Python层做if someobj is True:
一样。当someobj
为1
或非空str
时,如果Pythonic代码很少关注True
或False
,则会将其视为false而是“真实性”和“虚假性”。
另外,这个:
PyObject *b = Py_RETURN_TRUE;
是错误的。这将增加PyTrue
并返回它;后续代码都不会执行。你想要:
PyObject *b = Py_True;
借用参考文献,添加后续内容:
Py_INCREF(b);
如果你打算稍后返回它,那么使它成为一个拥有的引用(因为它是一个不会消失的单例,使用借用的引用是正常的,除非你知道它将在DECREF
稍后进行,例如因为你把它归还并将所有权转给了一个不知道它是借来的参考的来电者。
答案 1 :(得分:-1)
答案是在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
的所有值实际上都引用了这两个全局{ {1}}和Py_True
个对象。使用Py_False
返回此类对象时,引用计数会递增。
这意味着指向值Py_RETURN_TRUE
的PyObject的每个C指针实际上指向相同的内存地址。因此,检查Py_True
是真还是假是如此简单:
PyObject
使用/* 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 */ }
来验证相关对象是否为Python布尔值通常是个好主意。