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

标签 python python-2.7

我的假设是,定义 _ _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/

相关文章:

python - 如何将标准输出和标准错误重定向到 Python 中的记录器

python 当我使用 '__slots__' 时

python - 如何确定 DAG 在 Airflow 中是否暂停/未暂停?

python - 替换列表中子列表中所有出现的项目

python - 使用 subprocess.Popen() 或 subprocess.check_call() 时程序卡住

macos - pip install xgboost with error Command "python setup.py egg_info"failed with error code 1 on mac (Python 2.7)

python-2.7 - PyInstaller 无法处理简单的 HelloWorld 程序

python - 在每行开头添加前缀不起作用

python - 是否需要范围(len(a))?

python - 无法将度数符号输入 raw_input