2014-10-28 2 views
4

Я пытаюсь понять, оператор перегрузку в Python, и я написал небольшие программы, которые перегружают __getitem__() метод и вызывают цикл:__getitem__ перегрузки в питоне

class Ovl: 
    data = [1,2,3,4,5] 
    def __getitem__(self, index): 
     return "Hiii" 

x=Ovl() 

for item in x: 
    print item 

Эта программа переходит в к бесконечному циклу печать «Hiii». Я хотел бы знать причину этого.

ответ

10

Согласно object.__getitem__ ПРИМЕЧАНИЮ

ПРИМЕЧАНИЕ: for петли ожидать, что IndexError будет поднят для незаконных индексов для обеспечения надлежащего обнаружения конца последовательности.

>>> 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 
1

перегрузкой __getitem__ фактически позволяет сделать что-то вроде этого:

>>> x = Ovl() 
>>> x[6] 
'Hi' 
>>> x[8] 
'Hi' 

Если вы хотите реализовать Перебор вашего класса с for, вам нужно перегрузить __iter__ метод (см здесь: How to implement __iter__(self) for a container object (Python)).

Причина, по которой ваш цикл работает бесконечно, заключается в том, что реализация по умолчанию __iter__, по-видимому, вызывает __getitem__ внутренне. На самом деле, ваш цикл вызывает __getitem__(0), __getitem__(1), __getitem__(2), ... последовательно, поэтому кажется, что он работает бесконечно.

Если вы измените __getitem__ метод:

def __getitem__(self, index): 
    return index, "Hi" 

Вы можете увидеть именно то, что происходит:

>>> x = Ovl() 
>>> for item in x: 
    print item 

(0, 'Hi') 
(1, 'Hi') 
(2, 'Hi') 
(3, 'Hi') 
(4, 'Hi') 
(5, 'Hi') 
(6, 'Hi') 
...