__getitem__在python中重载

时间:2014-10-28 14:59:16

标签: python python-2.7 operator-overloading

我试图理解python中的运算符重载,我编写了一个重载__getitem__()方法并调用for循环的小程序:

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

x=Ovl()

for item in x:
    print item

这个程序进入无限循环打印“Hiii”。我想知道背后的原因。

2 个答案:

答案 0 :(得分:12)

根据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 :(得分:1)

__getitem__的重载实际上允许您执行以下操作:

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

如果您希望使用for对您的班级进行迭代,则需要重载__iter__方法(请参阅此处:How to implement __iter__(self) for a container object (Python))。

循环运行无限的原因是__iter__的默认实现显然在内部调用__getitem__。实际上,您的for循环会依次调用__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')
...