19

我想使用类似的东西:

class Board():
    ...
    def __getitem__(self, y, x):
        return self.board[y][x]

但不幸的是,当我打电话时:

board[x][y]

我得到: TypeError: __getitem__() takes exactly 3 arguments (2 given)

4

5 回答 5

23

当您这样做时,board[x][y]您将导致两次调用,__getitem__因为您正在执行两个单独的访问:[x]是一个和[y]另一个。没有办法直接在__getitem__; 您必须board[x]返回某种可[y]用于获取单个项目的子对象。您可能想要的是__getitem__接受一个元组:

def __getitem__(self, tup):
    y, x = tup
    return self.board[y][x]

然后做:

board[x, y]

__getitem__(请注意,您将 x 和 y 的顺序在和---之间切换,board[x][y]这是故意的吗?)

于 2013-07-04T21:30:01.523 回答
5

您可能需要考虑使用以下语法:

board[(x, y)]

它不太漂亮,但它允许您简单地拥有多维数组。实际上是任意数量的维度:

board[(1,6,34,2,6)]

通过将 board 设为 defaultdict,您甚至可以拥有稀疏字典:

board[(1,6,34,2,6)]

>>> from collections import defaultdict
>>> board = defaultdict(lambda: 0)
>>> board[(1,6,8)] = 7
>>> board[(1,6,8)]
7
>>> board[(5,6,3)]
0

如果你想要比这更高级的东西,你可能想要NumPy

于 2013-07-04T21:58:11.347 回答
3

board[x][y]意思是board.__getitem__(x).__getitem__(y),所以Board.__getitem__不得不返回某种也支持__getitem__和记住的观点x。这有点工作,但对于某些用例(任何涉及传递该视图的任何事情)来说,它非常方便。

另一种选择是board[x, y],这意味着board.__getitem__((x, y))。请注意,这会将一个元组传递给__getitem__,您必须手动解包(在 2.x 中有用于执行此操作的语法糖,但它有点晦涩,并且在 3.x 中也消失了,因此您可能希望在未来移植工作的兴趣)。

于 2013-07-04T21:30:48.137 回答
3

做就是了:

class Board():
    def __getitem__(self, x):
        return self.board[x]

因为当你调用b[x][y]它时实际上调用__getitem__()了两次,如下所示:

import numpy as np
b = Board()
b.board = np.random.random((3,3,3))
print (b[2][0]==(b[2])[0]).all()
#True

但最好是 subclass np.ndarray,这样你就不必重新实现这个方法:

class Board(np.ndarray):
    pass
于 2013-07-04T21:49:13.330 回答
-1

说 b 是类对象 b = Board()。当你正在寻找B[0][0] __getitem__不会正常工作。相反,我们可以做的是设置 b 的数据等于一个新变量。

boardData = b.data

print(boardData[0][0]) 
于 2020-05-04T20:26:19.943 回答