【问题标题】:Checking if PyObject is nullptr检查 PyObject 是否为 nullptr
【发布时间】:2016-01-16 11:41:51
【问题描述】:

我正在使用 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) 检查,但实践中似乎没有任何结果。

问题:如何删除列表中的 &lt;NULL&gt; 条目?

【问题讨论】:

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


    【解决方案1】:

    试试this solution

    if (handle == Py_None) {
        continue;
    }   
    

    或者

    int PyObject_Not(PyObject *o)

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

    否则,也许您可​​以检查handle 的字符串表示形式。根据the documentation,您也许可以使用一些组合

    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;
    }
    

    【讨论】:

      【解决方案2】:

      问题在于如何分配列表。来自the documentationPyList_New(Py_ssize_t len)

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

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

      解决办法是:

      1. 创建一个空列表(传递len 0)并保持其余代码相同(使用PyList_Append),或者
      2. 为列表分配一个大小,并使用PyList_SetItem 而不是追加。如果您使用这种方法,请注意 PyList_setItem 窃取了一个引用(因此您必须使用 incref handle),并且您想要的列表长度仅包括带有 getHandle()!=NULL 的那些对象。

      【讨论】:

        猜你喜欢
        • 2023-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-20
        • 1970-01-01
        相关资源
        最近更新 更多