Я уже посмотрел на этот вопрос: итераторы 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, но я не хочу делать это, поскольку он выставляет реализацию моего Класса исключений.
Метод __ ITER __
должен вернуть объект iTerator, но вы возвращаете объект списка. Используйте
def __iter__(self):
return iter(self._values)
вместо этого, чтобы исправить это. Из документации для объекта .__ ITER __
(мой выделение):
Этот метод называется, когда итератор требуется для контейнера. Этот метод должен вернуть новый объект ITERATOR , который может повторять все объекты в контейнере.
def __iter__(self):
return iter(self._values)
Или более общий:
def __iter__(self):
for x in self._values:
yield x
__ iter __
должен возвращать итератор, а не список.
Попробуйте следующее:
def __iter__(self):
return iter(self._values)
Вы также можете сделать:
def __iter__(self):
for val in self._values:
yield val
Но я не могу придумать причину, по которой вам нужно было бы сделать это вместо использования iter ()