Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does defining __getitem__ on a class make it iterable in python?

Why does defining __getitem__ on a class make it iterable?

For instance if I write:

class b:
  def __getitem__(self, k):
    return k

cb = b()

for k in cb:
  print k

I get the output:

0
1
2
3
4
5
6
7
8
...

I would really expect to see an error returned from "for k in cb:"

like image 654
grieve Avatar asked May 29 '09 15:05

grieve


People also ask

What makes something iterable in Python?

Iterable is an object which can be looped over or iterated over with the help of a for loop. Objects like lists, tuples, sets, dictionaries, strings, etc. are called iterables. In short and simpler terms, iterable is anything that you can loop over.

What is an iterable class in Python?

In a nutshell, an Iterable in Python is an object over which you iterate its elements while an Iterator, is an object that returns an Iterable object and is used to produce the values during the iteration.

Why is string iterable in Python?

The list numbers and string names are iterables because we are able to loop over them (using a for-loop in this case).

Which function creates an object which creates an iterable?

An object is called iterable if we can get an iterator from it. Most built-in containers in Python like: list, tuple, string etc. are iterables. The iter() function (which in turn calls the __iter__() method) returns an iterator from them.


2 Answers

Iteration's support for __getitem__ can be seen as a "legacy feature" which allowed smoother transition when PEP234 introduced iterability as a primary concept. It only applies to classes without __iter__ whose __getitem__ accepts integers 0, 1, &c, and raises IndexError once the index gets too high (if ever), typically "sequence" classes coded before __iter__ appeared (though nothing stops you from coding new classes this way too).

Personally, I would rather not rely on this in new code, though it's not deprecated nor is it going away (works fine in Python 3 too), so this is just a matter of style and taste ("explicit is better than implicit" so I'd rather explicitly support iterability rather than rely on __getitem__ supporting it implicitly for me -- but, not a bigge).

like image 133
Alex Martelli Avatar answered Sep 19 '22 21:09

Alex Martelli


If you take a look at PEP234 defining iterators, it says:

1. An object can be iterated over with "for" if it implements
   __iter__() or __getitem__().

2. An object can function as an iterator if it implements next().
like image 36
Edward Dale Avatar answered Sep 18 '22 21:09

Edward Dale