如何测试 PyObject 是否有迭代器

the*_*own 9 c python

我正在实现一个 C 函数作为 Python 的扩展。在里面abstract.h,我发现了以下内容:

/* ==== Iterators ================================================ */

/* Takes an object and returns an iterator for it.
   This is typically a new iterator but if the argument is an iterator, this
   returns itself. */
PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *);

/* Returns 1 if the object 'obj' provides iterator protocols, and 0 otherwise.

   This function always succeeds. */
PyAPI_FUNC(int) PyIter_Check(PyObject *);
Run Code Online (Sandbox Code Playgroud)

当我尝试PyObject_GetIter在明显不可迭代的对象(如数字)上使用迭代器时,出现错误SystemError: <built-in function xxx> returned a result with an error set

static PyObject *my_method(PyObject *self, PyObject *args) 
{
    PyObject *obj;
    PyArg_ParseTuple(args, "O", &obj)
    //  printf("\ncheck %d",PyIter_Check(obj)); // always 0
    PyObject *iter = PyObject_GetIter(obj); // throws error
    return PyLong_FromLong(0);
}
Run Code Online (Sandbox Code Playgroud)

我想自己处理错误。所以我尝试使用PyIter_Check来测试对象是否有迭代器。但是,此函数为我提供的所有对象返回 0,包括可迭代对象。

我认为这可能是由PyAPI_FUNC()宏引起的,但我在其中找到了它,pyport.h而且似乎只添加了__declspec.

  • 为什么该函数PyIter_Check对所有对象都返回零?

Dav*_*ing 3

PyIter_Check用于检查一个对象是否迭代器,而不是它是否可以提供迭代器。似乎没有\xe2\x80\x99t 是一个PyIterable_Check.

\n\n

此外,Python 几乎强制执行 EAFP:因为任何东西都可能提供__iter__引发异常的异常,所以你必须检查是否有错误PyObject_GetIter,因此函数的唯一目的*_Check是提供早期的健全性检查(有时提供更好的错误消息)。

\n