检查PyObject是否为nullptr

时间:2015-10-17 22:17:55

标签: python c++ python-2.7 c++11

我使用Python C Api来填充包含PyObject*元素的列表,并将其传递给Python中的函数。一切都很顺利,但有一个问题 - Python中的转移列表包含奇数<NULL>个条目。 List也包含“想要的”对象,所以看起来它几乎正在工作。

这是列表预览:

[<NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <NULL>, <dbg.TBack object at 0x19675870>, <interface.Grid object at 0x196758B0>, <interface.Grid object at 0x196758F0>, <interface.slp object at 0x196757D0>]

我用于填写Python C API列表的代码。

PyObject* list = PyList_New(objectsList.size());
PyObject* handle;

for (auto child : objectsList) {
    if (!child) {
        continue;
    }

    handle = child->GetHandle(); // handle = PyObject*
    if (!handle) {
        continue;
    }

    PyList_Append(list, handle);
}

return list; // push

我尝试添加if(!handle)项检查,但实际上似乎没有任何结果。

问题:如何摆脱列表中的<NULL>条目?

2 个答案:

答案 0 :(得分:2)

尝试this solution

if (handle == Py_None) {
    continue;
}   

或者

  

int PyObject_Not(PyObject * o)

     

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

否则,也许您可​​以查看handle的字符串表示。根据{{​​3}},您可以使用

的某种组合
int       PyObject_Compare(PyObject *o1, PyObject *o2)
PyObject* PyObject_Repr   (PyObject *o)

我在想像

这样的东西
PyObject* null_str   = Py_BuildValue("null_str", "<NULL>");
PyObject* handle_str = PyObject_Repr(handle);
if (!PyObject_Compare(null_str, handle_str)) {
    continue;
}

答案 1 :(得分:1)

问题在于如何分配列表。来自PyList_New(Py_ssize_t len)的{​​{1}}:

  

注意:如果len大于零,则返回的列表对象的项目将设置为NULL。因此,在使用PySequence_SetItem()将所有项目设置为实际对象之前,不能使用PyList_SetItem()等抽象API函数或将对象公开给Python代码。

即。它正在制作一个“len”空指针的列表,而不是制作一个带有预分配空间的空列表。

解决方案是:

  1. 制作一个空列表(传递len 0)并保持其余代码相同(使用PyList_Append)或
  2. 使用大小分配列表,并使用PyList_SetItem而不是追加。您使用此方法时请注意PyList_setItem窃取引用(因此您必须incref handle),并且您希望列表的长度仅包含getHandle()!=NULL {1}}。
相关问题