Python 伪序列对象:需要终止异常吗?

Python 伪序列对象:需要终止异常吗?,python,python-2.7,Python,Python 2.7,我接受这样的假设,即定义\uu len\uuu和\uu getitem\uuu方法对于一个类来说已经足够了,因此它的实例可以通过instance:中的for元素进行迭代,直到它违反了一个示例。我的原始代码完全不同,但这很好地说明了问题进入了一个无休止的循环: class Limited(object): def __init__(self, size=5): self.size = size def __len__(self): return s

我接受这样的假设,即定义
\uu len\uuu
\uu getitem\uuu
方法对于一个类来说已经足够了,因此它的实例可以通过instance:中的
for元素进行迭代,直到它违反了一个示例。我的原始代码完全不同,但这很好地说明了问题进入了一个无休止的循环:

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
我找不到终止迭代循环的要求的具体参考,但如果不想遵守完整迭代器协议,则终止似乎需要索引器或StopIteration之类的异常

这是正确的吗?在哪里可以找到文件记录?

回答 是,需要索引器终止

文档 请参阅带有注释的文档:

注意:对于循环,预期索引器将为非法的 索引以允许正确检测序列的结尾

底层源代码 创建迭代器的逻辑在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__;()方法的开头添加两行:

这将输出一个有限序列:

0
10
20
30

只要实现
\uuu getItem\uuu
方法,python就会尝试从
0
infinite
访问所有索引,因此如果不指定何时停止,它将继续调用该方法

只需检查索引值是否高于大小,例如:

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

    def __len__(self):
        return self.size

    def __getitem__(self, item):
      if item < self.size:
        return item*10
      raise IndexError
类别限制(对象):
def uuu init uuuu(自身,大小=5):
self.size=大小
定义(自我):
返回自身大小
定义获取项目(自身,项目):
如果项目<自身尺寸:
退货项目*10
提升索引器
给你一个

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

    def __len__(self):
        return self.size

    def __getitem__(self, item):
      if item < self.size:
        return item*10
      raise IndexError