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__()的文档,其中包含以下注意事项:
基础源代码 创建迭代器的逻辑在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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |