我已经看过这个问题:Python iterators – how to dynamically assign self.next within a new style class?
但这对我没有帮助,因为我想迭代一个列表的错误属性(即已经可迭代),而不必显式使用该属性。我希望这样做:
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)
然而,在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'
我知道我可以从_values中删除_然后遍历e.values但是我不想这样做,因为它暴露了我的Exception类的实现。
答案 0 :(得分:20)
__iter__
方法应该返回一个迭代器对象,但是你返回一个列表对象。使用
def __iter__(self):
return iter(self._values)
而是解决这个问题。来自object.__iter__
的文档(我的重点):
当容器需要迭代器时,将调用此方法。此方法应返回新迭代器对象,它可以迭代容器中的所有对象。
答案 1 :(得分:5)
def __iter__(self):
return iter(self._values)
或更通用:
def __iter__(self):
for x in self._values:
yield x
答案 2 :(得分:1)
__iter__
需要返回迭代器,而不是列表。
试试这个:
def __iter__(self):
return iter(self._values)
你也可以这样做:
def __iter__(self):
for val in self._values:
yield val
但我无法想到你需要这样做的原因,而不是使用iter()