加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 伪序列对象:终止需要异常?

发布时间:2020-12-20 12:02:26 所属栏目:Python 来源:网络整理
导读:我生活在假设中,定义_ _len _ _和_ _getitem_ _方法对于一个类就足够了,所以它的实例可以通过实例中的for元素迭代,直到它被违反了一个例子.我的原始代码完全不同,但这显示了很好地进入无限循环的问题: class Limited(object): def __init__(self,size=5): s
我生活在假设中,定义_ _len _ _和_ _getitem_ _方法对于一个类就足够了,所以它的实例可以通过实例中的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

我找不到对终止迭代循环的要求的具体引用,但似乎如果不想遵守完整的Iterator协议,则需要像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,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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读