我为连接4游戏创建了一个Board
类,它使用了一个列表列表。我想让对象支持索引板的行和列:
class Test:
def __init__(self, cols, rows):
self.cols = cols
self.rows = rows
self.data = [[' '] * cols for row in range(rows)]
def __iter__(self):
yield from self.data
def __getitem__(self, row):
pass
# what should this be?
我知道我需要定义__getitem__
但是这种方法应该允许b[1][1]
之类的语法?我已经看了some past questions,但我似乎无法找到我正在寻找的答案。
修改:也许以下是正确的做事方式?
def __getitem__(self, row):
return self.data[row]
答案 0 :(得分:6)
您需要了解的基本事项是,对于b[1][2]
这样的语法,有两个 __getitem__
调用。首先,调用b.__getitem__(1)
,并返回一个对象。然后,调用returned_object.__getitem__(2)
。因此,无论班级b
是什么,都无法完全控制整个过程。
在上面的示例中,如果您将其定义为
def __getitem__(self, row):
return self.data[row]
然后b[1][2]
将首先调用b.__getitem__(1)
,这将返回self.data[1]
,这将是一个列表。该列表还支持__getitem__
,因此将调用下一个list.__getitem__(2)
。
如果你想控制两者那些,那么你需要定义另一个表示列的类,父类需要返回其中一个对象而不是原始列表,然后可以为自定义功能实现自己的__getitem__
。
其他选择是支持b[1,2]
这样合法的语法 - 它会将b.__getitem__((1,2))
称为(1,2)
作为元组(您可以将任何放在那里)真的),但它并不那么自然。
答案 1 :(得分:3)
您可以返回子列表
所代表的row
def __getitem__(self, row):
return self.data[row]
例如
>>> t = Test(2,5)
>>> t.data
[[' ', ' '],
[' ', ' '],
[' ', ' '],
[' ', ' '],
[' ', ' ']]
获得一行
>>> t[1]
[' ', ' ']
获取元素
>>> t[1][0]
' '
请注意,上面示例中的第二个操作[0]
不需要您定义它,因为它只会从__getitem__
调用list
,因为它就是这样。< / p>
答案 2 :(得分:1)
只需返回行:
def __getitem__(self, row):
return self.data[row]