简体   繁体   English

Python:为什么我不能遍历列表?我的异常课程是否被禁止?

[英]Python: Why can't I iterate over a list? Is my exception class borked?

I've already looked at this question: Python iterators – how to dynamically assign self.next within a new style class? 我已经看过这个问题: Python迭代器 - 如何在新的样式类中动态分配self.next?

but this doesn't help me because I want to iterate of an attribute of the error which is a list (ie, already iterable) without having to use the attribute explicitly. 但这对我没有帮助,因为我想迭代一个列表的错误属性(即已经可迭代)而不必明确使用该属性。 I'm looking to do this: 我希望这样做:

class SCE(Exception):
    """
    An error while performing SCE functions.
    """
    def __init__(self, value=None):
        """
        Message: A string message or an iterable of strings.
        """
        if value is None:
            self._values = ['A general SCE error has occured.']
        elif isinstance(value, str):
            self._values = [value]
        else:
            self._values = list(value)

    def __iter__(self):
        return self._values

    def __repr__(self):
        return repr(self._values)

However, in the shell I get this: 但是,在shell中我得到了这个:

try:
    raise CSE(['error one', 'error two'])
except CSE, e:
    for i in e:
        print(i)
Traceback (most recent call last):
  File "(stdin)", line 1, in (module)
TypeError: iter() returned non-iterator of type 'list'

I know I could remove the _ from _values and then iterate over e.values but I don't want to do that as it exposes the implementation of my Exception class. 我知道我可以从_values中删除_然后迭代e.values但我不想这样做,因为它暴露了我的Exception类的实现。

The __iter__ method should return an iterator object, but you are returning a list object. __iter__方法应该返回一个迭代器对象,但是你返回一个列表对象。 Use 使用

def __iter__(self):
    return iter(self._values)

instead to fix this. 而是解决这个问题。 From the documentation for object.__iter__ (my highlighting): 来自object.__iter__的文档(我的突出显示):

This method is called when an iterator is required for a container. 当容器需要迭代器时,将调用此方法。 This method should return a new iterator object that can iterate over all the objects in the container. 此方法应返回一个新的迭代器对象 ,该对象可以迭代容器中的所有对象。

def __iter__(self):
    return iter(self._values)

Or a more generic: 或者更通用的:

def __iter__(self):
    for x in self._values:
        yield x

__iter__ needs to return an iterator, not a list. __iter__需要返回一个迭代器,而不是一个列表。

Try this: 试试这个:

    def __iter__(self):
        return iter(self._values)

You could also do: 你也可以这样做:

    def __iter__(self):
        for val in self._values:
            yield val

But I can't really think of a reason you'd need to do that instead of using iter() 但我真的不能想到你需要这样做的原因而不是使用iter()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM