admin管理员组

文章数量:1123084

I'm trying to clear a pybind11 list. In version 2.13 of Pybind11, this works great, there's a clear() method that does the following:

    void clear() /* py-non-const */ {
        if (PyList_SetSlice(m_ptr, 0, PyList_Size(m_ptr), nullptr) == -1) {
            throw error_already_set();
        }
    }

So I can do things like:

py::list myList;
// todo: append some data, do some things
myList.clear();

And this works fine. However, I'm now working in an environment with an older Pybind11. I believe it's version 2.6.2.

Now, if I try the same thing, I get error: ‘class pybind11::list’ has no member named ‘clear’. And this appears to be true. If I look at the source, the clear() method no longer exists:

class list : public object {
public:
    PYBIND11_OBJECT_CVT(list, object, PyList_Check, PySequence_List)
    template <typename SzType = ssize_t,
              detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>
    // Some compilers generate link errors when using `const SzType &` here:
    explicit list(SzType size = 0) : object(PyList_New(ssize_t_cast(size)), stolen_t{}) {
        if (!m_ptr) {
            pybind11_fail("Could not allocate list object!");
        }
    }
    size_t size() const { return (size_t) PyList_Size(m_ptr); }
    bool empty() const { return size() == 0; }
    detail::list_accessor operator[](size_t index) const { return {*this, index}; }
    template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>
    detail::item_accessor operator[](T &&o) const {
        return object::operator[](std::forward<T>(o));
    }
    detail::list_iterator begin() const { return {*this, 0}; }
    detail::list_iterator end() const { return {*this, PyList_GET_SIZE(m_ptr)}; }
    template <typename T>
    void append(T &&val) /* py-non-const */ {
        if (PyList_Append(m_ptr, detail::object_or_cast(std::forward<T>(val)).ptr()) != 0) {
            throw error_already_set();
        }
    }
    template <typename IdxType,
              
              typename ValType,
              detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>
    void insert(const IdxType &index, ValType &&val) /* py-non-const */ {
        if (PyList_Insert(m_ptr,
                          ssize_t_cast(index),
                          detail::object_or_cast(std::forward<ValType>(val)).ptr())
            != 0) {
            throw error_already_set();
        }
    }
};

So, how do I clear this list?

I can try to replicate the function by casting the list to a PyObject*:

  PyList_SetSlice(py::cast<PyObject*>(myList), 0,
                  PyList_Size(py::cast<PyObject*>(myList)), nullptr);

But is this seriously the intended way to clearing a list? Seems a bit weird.

本文标签: cHow to clear pylist when clear() does not exist in Pybind11 26Stack Overflow