我读过有关Python类(link)的内容,这似乎是我遇到的问题。
以下是我班级和其他代码的摘录:
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的列表似乎也会受到影响。
所以我的问题:
答案 0 :(得分:2)
self.__board[:]
创建一个新列表,其中包含对self.__board
中所有相同对象的引用。由于self.__board
包含列表,并且列表是可变的,因此您最终会使用部分别名数据的两个s_board
实例,而更改一个会影响另一个。
正如Raymond Hettinger建议的那样,您可以使用copy.deepcopy
来保证您获取对象的真实副本并且不共享任何数据。我主要说,因为我相信有一些奇怪的对象deepcopy
不会起作用,但对于像列表和简单类这样的正常事情,它会正常工作。
我还有一个额外的建议。您调用b = s_board()
,即为新空白板构建列表的所有工作,然后通过分配到b.__board
和b.__solved
将其丢弃。看起来好像做以下事情会更好:
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
的独特副本,而无需分配然后丢弃新的空白板。
答案 1 :(得分:0)
尝试使用deepcopy()
代替copy()
copy()
如果能够插入引用,deepcopy()
应该复制所有成员而不使用引用。
答案 2 :(得分:0)
正在分享内部列表。这是一篇解释发生了什么的文章:http://www.python-course.eu/deep_copy.php
要修复代码,您可以使用 copy.deepcopy 确保没有共享数据:
def copy(self):
b = s_board()
b.__board = copy.deepcopy(self.__board)
b.__solved = copy.deepcopy(self.__solved)
return b