I've already looked at this question: Python iterators – how to dynamically assign self.next within a new style class?
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:
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.
The __iter__
method should return an iterator object, but you are returning a list object. Use
def __iter__(self):
return iter(self._values)
instead to fix this. From the documentation for object.__iter__
(my highlighting):
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With