[Tutor] making object iterable

Peter Otten __peter__ at web.de
Sat Feb 5 21:12:35 CET 2011


Alex Hall wrote:

> Hi all,
> I have a class which has a list as an attribute, meaning you must say
> something like:
> for result in obj.results: ...
> I want to make life a bit easier and let users just say:
> for result in obj: ...
> Here is what I have tried to make my class into an iterable one, yet I
> get an error saying that the class does not support indexing:

Please remember to always cut-and-paste code and traceback.
 
>  def __iter__(self):
>   #makes this class indexable instead of having to use its "results" list
>   return self.iterate()
> 
>  def iterate(self):
>   i=0
>   while i<len(self.results):
>    yield self.results[i]
>    i+=1
> 
> I am not sure why this does not work, unless I am misunderstanding
> something about iterators and iterables? I thought an iterable, which
> is what I am shooting for, was an iterator on steroids, allowing
> indexing, multiple passes over the list, and all that. Do I want to
> make this an iterator instead of an iterable?

It *does* work:

>>> class A(object):
...     def __init__(self, results):
...             self.results = results
...     def __iter__(self):
...             return self.iterate()
...     def iterate(self):
...             i = 0
...             while i < len(self.results):
...                     yield self.results[i]
...                     i += 1
...
>>> a = A("abc")
>>> for item in a:
...     print item
...
a
b
c

Perhaps self.results is not what you think it is. Check by adding the 
apprpriate print statement.

By the way, there are simpler alternatives to delegate iteration to an 
attribute:

>>> class B(object):
...     def __init__(self, results):
...             self.results = results
...     def __iter__(self):
...             return iter(self.results)
...
>>> b = B("abc")
>>> for item in b:
...     print item
...
a
b
c




More information about the Tutor mailing list