用 tp_iternext 或 PyIter_Next 迭代差异
Difference iterating with tp_iternext or PyIter_Next
如果我编写一个 C 函数来处理可迭代对象,那么我会先创建一个迭代器,然后循环遍历它。
iterator = PyObject_GetIter(sequence);
if (iterator == NULL) {
return NULL;
}
while (( item = PyIter_Next(iterator) )) {
...
}
这很好用,但我也看到一些函数使用 tp_iternext
:
iterator = PyObject_GetIter(sequence); // ....
iternext = *Py_TYPE(iterator)->tp_iternext;
while (( item = iternext(iterator) )) {
...
}
第二种方法似乎更快(我只有一个数据点:我的 Windows 计算机和我的 msvc 编译器)。
iternext
方法更快是否只是巧合,这两者之间有什么显着差异吗?
python 文档的链接:
PyIter_Next,
tp_iternext
我已经阅读过它们,但对我来说不清楚何时以及为什么应该首选它们。
source code for PyIter_Next
显示它只是检索 tp_iternext
插槽并调用它 并清除可能发生或未发生的 StopIteration
异常.
如果您显式使用 tp_iternext
,则在用尽迭代器时必须检查此 StopIteration
。
顺便说一下:tp_iternext
的文档还说:
iternextfunc PyTypeObject.tp_iternext
An optional pointer to a function that returns the next item in an iterator. When the iterator is exhausted, it must return NULL
; a
StopIteration
exception may or may not be set. When another error
occurs, it must return NULL
too. Its presence signals that the
instances of this type are iterators.
虽然 PyIter_Next
的文档中没有这样的提及。
所以 PyIter_Next
是简单 和安全 遍历迭代器的方法。你可以使用 tp_iternext
但你必须小心不要在最后触发 StopIteration
异常。
如果我编写一个 C 函数来处理可迭代对象,那么我会先创建一个迭代器,然后循环遍历它。
iterator = PyObject_GetIter(sequence);
if (iterator == NULL) {
return NULL;
}
while (( item = PyIter_Next(iterator) )) {
...
}
这很好用,但我也看到一些函数使用 tp_iternext
:
iterator = PyObject_GetIter(sequence); // ....
iternext = *Py_TYPE(iterator)->tp_iternext;
while (( item = iternext(iterator) )) {
...
}
第二种方法似乎更快(我只有一个数据点:我的 Windows 计算机和我的 msvc 编译器)。
iternext
方法更快是否只是巧合,这两者之间有什么显着差异吗?
python 文档的链接: PyIter_Next, tp_iternext 我已经阅读过它们,但对我来说不清楚何时以及为什么应该首选它们。
source code for PyIter_Next
显示它只是检索 tp_iternext
插槽并调用它 并清除可能发生或未发生的 StopIteration
异常.
如果您显式使用 tp_iternext
,则在用尽迭代器时必须检查此 StopIteration
。
顺便说一下:tp_iternext
的文档还说:
iternextfunc PyTypeObject.tp_iternext
An optional pointer to a function that returns the next item in an iterator. When the iterator is exhausted, it must return
NULL
; aStopIteration
exception may or may not be set. When another error occurs, it must returnNULL
too. Its presence signals that the instances of this type are iterators.
虽然 PyIter_Next
的文档中没有这样的提及。
所以 PyIter_Next
是简单 和安全 遍历迭代器的方法。你可以使用 tp_iternext
但你必须小心不要在最后触发 StopIteration
异常。