我试图理解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”。我想知道背后的原因。
答案 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')
...