gpt4 book ai didi

python - 伪序列对象 : Exception needed to terminate?

转载 作者:太空宇宙 更新时间:2023-11-03 13:10:03 26 4
gpt4 key购买 nike

我的假设是,定义 _ _len_ __ _getitem_ _ 方法对于一个类来说已经足够了,因此它的实例可以通过 for element in instance:,直到它违反了一个例子。我的原始代码完全不同,但这表明问题很好地进入了无限循环:

class Limited(object):
def __init__(self, size=5):
self.size = size

def __len__(self):
return self.size

def __getitem__(self, item):
return item*10

if __name__ == "__main__":
test = Limited(4)
assert len(test) == 4

for q in test:
print q

我找不到对终止迭代循环的要求的具体引用,但如果不想遵守完整的 Iterator 协议(protocol),似乎需要像 IndexError 或 StopIteration 这样的异常来终止。

这是否正确,在哪里可以找到它的记录?

最佳答案

回答

是的,需要一个IndexError 来终止。

文档

请参阅 __getitem__() 的文档其中有注释:

Note for loops expect that an IndexError will be raised for illegal indexes to allow proper detection of the end of the sequence.

底层源码

创建迭代器的逻辑在Objects/iterobject.c中:

static PyObject *
iter_iternext(PyObject *iterator)
{
seqiterobject *it;
PyObject *seq;
PyObject *result;

assert(PySeqIter_Check(iterator));
it = (seqiterobject *)iterator;
seq = it->it_seq;
if (seq == NULL)
return NULL;
if (it->it_index == PY_SSIZE_T_MAX) {
PyErr_SetString(PyExc_OverflowError,
"iter index too large");
return NULL;
}

result = PySequence_GetItem(seq, it->it_index);
if (result != NULL) {
it->it_index++;
return result;
}
if (PyErr_ExceptionMatches(PyExc_IndexError) ||
PyErr_ExceptionMatches(PyExc_StopIteration))
{
PyErr_Clear();
Py_DECREF(seq);
it->it_seq = NULL;
}
return NULL;
}

示例

要修复 OP 的代码,只需在 __getitem__() 方法的开头添加两行:

class Limited(object):
def __init__(self, size=5):
self.size = size

def __len__(self):
return self.size

def __getitem__(self, item):
if item >= len(self):
raise IndexError
return item*10

if __name__ == "__main__":
test = Limited(4)
assert len(test) == 4

for q in test:
print(q)

这会输出一个有限序列:

0
10
20
30

关于python - 伪序列对象 : Exception needed to terminate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45609473/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com