我试图在python中为类实现__getitem__
方法。我想尝试类似......
def __getitem__(self, key):
if isinstance(key, int):
return foo(key)
elif isinstance(key, slice):
return [foo(k) for k in key]
else:
raise TypeError("Invalid index.")
...但每当我真正尝试将其与切片一起使用时,我会收到'slice' object is not iterable
错误。在python中执行此操作的正确方法是什么?
答案 0 :(得分:5)
使用切片的indices()
方法,并将结果传递给range()
或xrange()
。
>>> slice(2, 5).indices(7)
(2, 5, 1)
>>> range(*slice(2, 5).indices(7))
[2, 3, 4]
>>> range(*slice(2, 10).indices(7))
[2, 3, 4, 5, 6]
答案 1 :(得分:1)
指数可能有效,但你也可以只使用切片的开始,停止和步骤,虽然它们可能是空的,所以你需要做这样的事情......
def __getitem__(self, key):
if isinstance(key, int):
return foo(key)
elif isinstance(key, slice):
start = key.start if key.start is not None else 0
stop = key.stop
step = key.step if key.step is not None else 1
return [foo(k) for k in range(start, stop, step)]
else:
raise TypeError("Invalid index.")
答案 2 :(得分:1)
您遇到的问题是,例外情况是:slice
对象不可迭代。我发现思考切片的最佳方式是它是一个给迭代器的指令,以确定它返回的内容。所以如果你想要得到这样的东西:
>>> L = [1, 2, 3, 4]
>>> L[1:3]
[2, 3]
(显然这是使用列表而不是自定义类的简化示例)
传递给__getitem__
的切片将具有一些您可以使用的属性:
>>> s = slice(1, 2, 3)
>>> s.start, s.stop, s.step
(1,2,3)
如果您说s = slice(1, 2)
,则step
属性将为None
。您可以使用此信息在__getitem__
中获取列表,元组或任何您想要的内容:
def __getitem__(self, i):
if isinstance(i, int):
return foo(i)
elif isinstance(i, slice):
return [foo(k) for k in self.bar[i]] # where bar is a list/tuple
这可行的原因是因为调用self.bar[i]
i
所在的切片与调用self.bar[1:2]
完全没有区别,因为1:2
只是slice
}对象是i
。
希望这有用!