[Tutor] How to override getting items from a list for iteration
Steven D'Aprano
steve at pearwood.info
Sun Feb 10 16:13:48 CET 2013
On 11/02/13 01:32, Walter Prins wrote:
> Hello,
>
> I have a program where I'm overriding the retrieval of items from a list.
> As background:
[...snip interesting but irrelevant background...]
> Here's a test application that demonstrates the issue:
[...snip overly complicated application...]
Here is a much simpler demonstration:
py> class MyList(list):
... def __getitem__(self, i):
... print "Checking item %d" % i
... return super(MyList, self).__getitem__(i)
...
py> x = MyList([2, 4, 8, 16])
py> x[3]
Checking item 3
16
py> for i in x:
... print "got %s" % i
...
got 2
got 4
got 8
got 16
> What's the best way to fix this problem? Do I need to maybe override
> another method, perhaps provide my own iterator implementation?
Pretty much. For lists, the __iter__ method returns a listiterator object
which efficiently iterates over the list items without calling __getitem__.
Try overriding your class' __iter__ method:
def __iter__(self):
for i in range(len(self)): # use xrange in Python 2
yield self[i]
(untested).
> For that
> matter, why doesn't iterating over the list contents fall back to calling
> __getitem__?
Probably as an optimization.
--
Steven
More information about the Tutor
mailing list