Python:为什么我无法遍历列表?我的异常类有问题吗?

14 投票
3 回答
10890 浏览
提问于 2025-04-15 18:45

我已经看过这个问题:Python 迭代器 - 如何在新风格类中动态分配 self.next?

但这对我没有帮助,因为我想要遍历一个错误的属性,而这个属性是一个列表(也就是说,它本身就可以被遍历),而不想明确使用这个属性。我想这样做:

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)

然而,在命令行中我得到的是:

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'

我知道我可以去掉 _values,然后遍历 e.values,但我不想那样做,因为这会暴露我异常类的实现细节。

3 个回答

1

__iter__ 这个方法需要返回一个迭代器,而不是一个列表。

你可以试试这个:

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

你也可以这样做:

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

不过我实在想不出有什么理由需要这样做,而不是直接用 iter()

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

或者一个更通用的:

33

__iter__ 方法应该返回一个迭代器对象,但你返回的是一个列表对象。你应该使用

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

来修复这个问题。根据 object.__iter__ 的文档(我强调的部分):

当需要一个迭代器来遍历一个容器时,会调用这个方法。这个方法应该返回一个新的迭代器对象,可以用来遍历容器中的所有对象。

撰写回答