Changes in __getitem__ in Python 2.0?

Tim Peters tim.one at home.com
Wed Feb 28 08:43:26 CET 2001


[Stephen W. Juranich]
> It's been a while since I've been playing with my Python toys (I've been
> banished to C++ land for a while <retch>).  I have a class with the
> following definition for __getitem__:
>
> def __getitem__(self, key):
>     # In some cases, I'm getting requests for data that are
>     # past the end of the list.  Given the sloppy nature of
>     # the hand-labelled data, I don't think this is too much
>     # of a problem, so I'll try this scheme.
>     try:
>         retval = self.data[key]
>     except IndexError:
>         retval = self.data[-1]
>
>     return retval
>
> I'm now encountering a problem with Python 2.0 that I never had
> with earlier versions (1.5 and 1.6 specifically).

Sorry, but this is hard to believe.  You Changed Something.

> I used to be able to do something like this:
>
> for foo in MyClass:
> 	print foo.member,

I'm assuming you meant to say that you're iterating over an *instance* of the
class that contains the __getitem__ shown above.

> But now when I do this, Python just starts spinning out of control in an
> infinite loop

Under the assumption above, it *should* be an infinite loop.  Also in 1.6,
1.5, ..., and 0.9.6.  Nothing relevant has ever changed here.  The "for"
protocol doesn't stop until __getitem__ raises an IndexError.  The only way
your __getitem__() above can raise an IndexError is if self.data is empty:
then the first iteration will try self.data[0], that will raise IndexError,
but then you'll catch IndexError, then the code will try self.data[-1], and
that will raise an uncaught IndexError (which terminates the loop).  So your
loop should terminate if and only if self.data is empty.

> ...
> I am assuming that the problem is because of the __getitem__ definition
> above.  Is there a way around this, or am I going to have to
> change a bunch of code to make this work on a new Python setup?

Again, it has nothing to do with 2.0, but you're not going to believe that
until you accept my challenge to show us a complete piece of executable code
that demonstrates the problem under 2.0 but not under earlier Pythons <wink>.
If your __getitem__ never raises IndexError, your "for" loop will never end;
that's always been the case.

or-the-problem-isn't-where-you-think-it-is-ly y'rs  - tim





More information about the Python-list mailing list