[抱歉,我是Python新手。虽然这似乎是一个非常基本的问题,但我在询问这些观众之前做了尽职调查,试图避免真正愚蠢的问题。
我正在试图找出从函数返回l值的正确习惯用法。假设我有一个包含64个对象的容器,我希望能够返回对这些对象的引用。
class ChessBoard:
def __init__(self):
self.squares = [None for x in range(64)]
square( row, col ):
return self.squares(row*8+col) <---- I'd like this to be l-value
然后,从课外我想:
board = ChessBoard()
board.square(0,0) = Piece( Shapes.ROOK, Colors.White ) <-- I'm getting an error here
board.square(0,1) = Piece( Shapes.BISHOP, Colors.White )
... etc.
所以,我希望函数'at'返回一个左值(类似于C ++中的引用),但是我找不到类似于语言中的引用或指针的东西。如果我在包含一个棋子的每个方格中存储列表,我可以做类似的事情:board.square(0,0)[0] = Piece - 但它似乎很疯狂(或者可能不是 - 正如我所说,我是语言的新手。)
您将如何处理此数据结构?
答案 0 :(得分:9)
在Python中,所有是一个参考。唯一的问题是None
不可变,因此您无法使用返回的引用来更改值。
您也无法覆盖赋值运算符,因此您不会遇到这种特殊行为。但是,一个好的,非常灵活的解决方案是覆盖__setitem__
和__getitem__
方法来为类实现订阅运算符([]
):
class ChessBoard(object):
def __init__(self):
self.squares = [None] * 64
def __setitem__(self, key, value):
row, col = key
self.squares[row*8 + col] = value
def __getitem__(self, key):
row, col = key
return self.squares[row*8 + col]
用法:
>>> c = ChessBoard()
>>> c[1,2] = 5
>>> c[1,2]
5
答案 1 :(得分:1)
正如尼克拉斯指出的那样,你无法返回一个l值。
但是,除了覆盖订阅之外,您还可以使用properties(描述符的应用程序:http://docs.python.org/howto/descriptor.html)来创建对象属性,该属性在读取或分配时运行代码。
答案 2 :(得分:1)
(不是在标题中回答你的问题,而是你的“你将如何处理这种数据结构?”问题:)对于你的数据结构,一个更加pythonic的解决方案是使用列表列表:
# define a function that generates an empty chess board
make_chess_board = lambda : [[None for x in xrange(8)] for y in xrange(8)]
# grab an instance
b = make_chess_board()
# play the game!
b[0][0] = Piece(Shapes.ROOK, Colors.White)
b[0][1] = Piece(Shapes.BISHOP, Colors.White)
# Or use tuples:
b[0][0] = (Shapes.ROOK, Colors.White)
b[0][1] = (Shapes.BISHOP, Colors.White)
答案 3 :(得分:1)
你可以尝试类似这样的事情,代价是不得不伪造[:]索引器:
class Board:
def __init__(self):
self.squares=[None for x in range(64)]
def square(self, row, col):
squares=self.squares
class Prox:
def __getitem__(self, i):
return squares[row*8+col]
def __setitem__(self, i, v):
squares[row*8+col]=v
return Prox()
然后你可以做
b=Board()
b.square(2,3)[:]=Piece('Knight')
if b.square(x,y)[:] == Piece('King') ...
等等。它实际上并不重要你放在[] s中,它只是必须是某种东西。
(从Proxies Perl6用于实现此目的的想法)