Reputation: 1948
I am trying to understand the operator overloading in python and I have written a small programs which overloads __getitem__()
method and calls a for loop:
class Ovl:
data = [1,2,3,4,5]
def __getitem__(self, index):
return "Hiii"
x=Ovl()
for item in x:
print item
This program goes in to a infinite for loop printing "Hiii". I would like to know the reason behind it.
Upvotes: 9
Views: 5303
Reputation: 303
The overloading of __getitem__
actually lets you do something like this:
>>> x = Ovl()
>>> x[6]
'Hi'
>>> x[8]
'Hi'
If you want to implement iterating over your class with for
, you need to overload __iter__
method (see here: How to implement __iter__(self) for a container object (Python)).
The reason for your loop running infinite thing is that the default implementation of __iter__
apparently calls __getitem__
internally. Actually, your for loop calls __getitem__(0)
, __getitem__(1)
, __getitem__(2)
, ...
sequentially, so it seems to run infinite.
If you would modify your __getitem__
method:
def __getitem__(self, index):
return index, "Hi"
You can see exactly what's happening:
>>> x = Ovl()
>>> for item in x:
print item
(0, 'Hi')
(1, 'Hi')
(2, 'Hi')
(3, 'Hi')
(4, 'Hi')
(5, 'Hi')
(6, 'Hi')
...
Upvotes: 4
Reputation: 369424
According to the object.__getitem__
NOTE,
NOTE:
for
loops expect that anIndexError
will be raised for illegal indexes to allow proper detection of the end of the sequence.
>>> class Ovl:
... data = [1,2,3,4,5]
... def __getitem__(self, index):
... if index >= 5:
... raise IndexError('End')
... return "Hiii"
...
>>> x=Ovl()
>>>
>>> for item in x:
... print item
...
Hiii
Hiii
Hiii
Hiii
Hiii
Upvotes: 17