我读到了有关 Python 类 ( link ) 的文章,这似乎是我遇到的问题。
这是我的类(class)和其他代码的摘录:
class s_board:
def __init__(self):
self.__board = [[n for n in range(1, 10)] for m in range(81)]
self.__solved = [False for m in range(81)]
def copy(self):
b = s_board()
b.__board = self.__board[:]
b.__solved = self.__solved[:]
return b
if __name__ == '__main__':
A = s_board()
B = A.copy()
B.do_some_operation_on_lists()
当我调用 B 的方法对列表执行某些操作时,A 的列表似乎也会受到影响。
所以我的问题:
- 我是否没有正确复制类(class)或列表?
- 这里还有其他问题吗?
- 如何修复它以便获得该类的新副本?
最佳答案
self.__board[:]
创建一个新列表,其中包含对 self.__board
中所有相同对象的引用。由于 self.__board
包含列表,并且列表是可变的,因此最终会得到两个带有部分别名数据的 s_board
实例,并且更改一个实例会影响另一个实例。
正如 Raymond Hettinger 所建议的,您可以使用 copy.deepcopy
来(大部分)保证您获取对象的真实副本并且不共享任何数据。我说大部分是因为我相信有一些奇怪的对象 deepcopy
无法工作,但对于列表和简单的类等普通事物来说它会工作得很好。
不过我还有一个额外的建议。您调用 b = s_board()
,它会全力为新的空白板构建列表,然后通过分配给 b.__board
来丢弃它们和b.__已解决
。似乎最好执行以下操作:
class s_board:
def __init__(self, board=None, solved=None):
if board is None:
self.__board = [[n for n in range(1, 10)] for m in range(81)]
else:
self.__board = copy.deepcopy(board)
if solved is None:
self.__solved = [False for m in range(81)]
else:
self.__solved = copy.deepcopy(solved)
def copy(self):
b = s_board(self.__board, self.__solved)
return b
现在,如果您调用 A = s_board()
,您将获得一个新的空白板,如果您调用 A.copy()
,您将获得 的不同副本>A
,无需分配然后丢弃新的空白板。
关于python - 如何在 Python 2.7 中复制类及其列表成员而不复制引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8146995/