[Tutor] making object iterable
Alex Hall
mehgcap at gmail.com
Sat Feb 5 21:50:22 CET 2011
On 2/5/11, Peter Otten <__peter__ at web.de> wrote:
> 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
Yes, I get the same thing. However, when you try to index, as in a[0],
you have problems. Here are two lines from my program:
for i in res: print i
This works as expected, printing every object in res.results, just as I wanted.
for i in range(len(res)): print str(i+1)+": "+str(res[i])
This gives me an error, on this line, that "TypeError: 'SearchResults'
object does not support indexing". So it seems that I can iterate over
the list, but not get at a given element. What builtin method do I
need to overload to do this?
>
> 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
True, and I have made this change.
>
>
> _______________________________________________
> Tutor maillist - Tutor at python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
--
Have a great day,
Alex (msg sent from GMail website)
mehgcap at gmail.com; http://www.facebook.com/mehgcap
More information about the Tutor
mailing list