python - 如何在 Python 2.7 中复制类及其列表成员而不复制引用?

标签 python class copy python-2.7

我读到了有关 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/

相关文章:

python - Keras:训练时出现值错误

javascript - 获取javascript类中静态方法的值

c# - 按值(value)传递?

jQuery 剪贴板复制

c++ - Cereal 和Boost序列化是否使用零拷贝?

Python:通用导入

python - 如何通过 python-eve 将图像上传到一些外部存储服务器,例如S3?

python - 从iterable设置numpy数组值的有效方法

python - 使用 tkinter 和类创建多个不同颜色的形状

javascript - 在对象内部使用 Ajax.Request 响应? - 原型(prototype)JS