Python unittest 更改变量似乎超出范围
Python unittest changing variable seemingly outside of scope
我有以下井字游戏代码:
class TicTacToeBoard:
board = [[0,0,0], [0,0,0], [0,0,0]]
def printBoard(self):
print(self.board)
def putPiece(self, position1, position2):
self.board[position1][position2] = 1
我正在对代码进行单元测试,如下:
def testestablishTicTacToeBoard(self):
test = TicTacToeBoard()
self.assertEqual(test.board, [[0,0,0],[0,0,0],[0,0,0]])
def testPutPiece(self):
test = TicTacToeBoard()
self.assertEqual(test.board, [[0,0,0],[0,0,0],[0,0,0]])
test.putPiece(1,1)
self.assertEqual(test.board, [[0,0,0],[0,1,0],[0,0,0]])
在我做第二个单元测试之前,第一个单元测试没有问题通过。一旦我进行了第二个单元测试,第一个单元测试不再通过:
self.assertEqual(test.board, [[0,0,0],[0,0,0],[0,0,0]])
AssertionError: Lists differ: [[0, 0, 0], [0, 1, 0], [0, 0, 0]] != [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
第二个单元测试中发生了什么导致第一个单元测试不再通过?
看起来是因为棋盘在所有实例之间共享(它是 class 属性,而不是实例属性)。
您可以用这个更改您的 class 代码,它应该可以工作:
class TicTacToeBoard:
def __init__(self):
# Now each instance (self) has its own board:
self.board = [[0,0,0], [0,0,0], [0,0,0]]
def printBoard(self):
print(self.board)
def putPiece(self, position1, position2):
self.board[position1][position2] = 1
如果你想说服自己真正发生了什么,你可以比较两个版本(instance/class属性):
class TicTacToeBoard:
shared_board = [[0,0,0], [0,0,0], [0,0,0]]
def __init__(self):
self.board = [[0,0,0], [0,0,0], [0,0,0]]
def __str__(self):
return (
f"Instance board: {self.board}\n"
f"Class board (shared): {self.shared_board}"
)
def putPiece(self, position1, position2):
self.board[position1][position2] = 1
self.shared_board[position1][position2] = 2
>>> b1 = TicTacToeBoard()
>>> b2 = TicTacToeBoard()
>>> b1.putPiece(1, 2)
>>> print(b1)
Instance board: [[0, 0, 0], [0, 0, 1], [0, 0, 0]]
Class board (shared): [[0, 0, 0], [0, 0, 2], [0, 0, 0]]
>>> print(b2)
Instance board: [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
Class board (shared): [[0, 0, 0], [0, 0, 2], [0, 0, 0]]
请注意第二个井字板 b2
没有位于 (1, 2)
位置但有两个位于 (1, 2)
.
位置
我有以下井字游戏代码:
class TicTacToeBoard:
board = [[0,0,0], [0,0,0], [0,0,0]]
def printBoard(self):
print(self.board)
def putPiece(self, position1, position2):
self.board[position1][position2] = 1
我正在对代码进行单元测试,如下:
def testestablishTicTacToeBoard(self):
test = TicTacToeBoard()
self.assertEqual(test.board, [[0,0,0],[0,0,0],[0,0,0]])
def testPutPiece(self):
test = TicTacToeBoard()
self.assertEqual(test.board, [[0,0,0],[0,0,0],[0,0,0]])
test.putPiece(1,1)
self.assertEqual(test.board, [[0,0,0],[0,1,0],[0,0,0]])
在我做第二个单元测试之前,第一个单元测试没有问题通过。一旦我进行了第二个单元测试,第一个单元测试不再通过:
self.assertEqual(test.board, [[0,0,0],[0,0,0],[0,0,0]])
AssertionError: Lists differ: [[0, 0, 0], [0, 1, 0], [0, 0, 0]] != [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
第二个单元测试中发生了什么导致第一个单元测试不再通过?
看起来是因为棋盘在所有实例之间共享(它是 class 属性,而不是实例属性)。
您可以用这个更改您的 class 代码,它应该可以工作:
class TicTacToeBoard:
def __init__(self):
# Now each instance (self) has its own board:
self.board = [[0,0,0], [0,0,0], [0,0,0]]
def printBoard(self):
print(self.board)
def putPiece(self, position1, position2):
self.board[position1][position2] = 1
如果你想说服自己真正发生了什么,你可以比较两个版本(instance/class属性):
class TicTacToeBoard:
shared_board = [[0,0,0], [0,0,0], [0,0,0]]
def __init__(self):
self.board = [[0,0,0], [0,0,0], [0,0,0]]
def __str__(self):
return (
f"Instance board: {self.board}\n"
f"Class board (shared): {self.shared_board}"
)
def putPiece(self, position1, position2):
self.board[position1][position2] = 1
self.shared_board[position1][position2] = 2
>>> b1 = TicTacToeBoard()
>>> b2 = TicTacToeBoard()
>>> b1.putPiece(1, 2)
>>> print(b1)
Instance board: [[0, 0, 0], [0, 0, 1], [0, 0, 0]]
Class board (shared): [[0, 0, 0], [0, 0, 2], [0, 0, 0]]
>>> print(b2)
Instance board: [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
Class board (shared): [[0, 0, 0], [0, 0, 2], [0, 0, 0]]
请注意第二个井字板 b2
没有位于 (1, 2)
位置但有两个位于 (1, 2)
.