为什么复制的对象与之前在 Python 中复制的对象具有相同的 ID?

Why copied objects have the same id as previously copied ones in Python?

我试图理解一个观察结果。 我有一个加载各种 Canvas 类 的应用程序,用户以后可以使用这些应用程序。这些 类 位于多个文件中。 例如.

canvas/
    bw.py
    colored.py
    oil.py

我像这样导入、实例化和复制这些对象:

canvas_files = os.listdir('images')
imported_canvs = []
    for canv in canvas_files:
        canv = __import__(canv.split('.')[0], fromlist=['Canvas'])
        try:
            new_canv = canv.Canvas()
            new_canv_copy = copy.copy(new_canv)
            imported_canvs.append(new_canv_copy)
        except AttributeError as ex:
             pass

之后,用户使用 imported_canvs 列表中的每个 Canvas 对象。但是,当我两次导入和实例化这些对象时(运行 for 再次循环),我可以看到 id(new_canv_copy) 与之前导入和实例化的对象相同。 这不会是一个问题,除非每个 Canvas 都有对每个实例都是唯一的设置,而这目前没有发生。每当用户更改一个 Canvas 中的设置时,它们会在复制的一个中自动更改。

为什么会这样,我做错了什么?

copy.copy 执行浅拷贝,这意味着任何对象都将指向现有对象。如果你想让里面的对象也被克隆,你需要使用copy.deepcopy

仅使用 copy.copy() 创建一个浅拷贝。在使用 copy.deepcopy().

复制对象时,您可能希望使用深拷贝

你可以在这里详细阅读有什么区别:https://docs.python.org/2/library/copy.html

我不知道 canv.Canvas() 里面做了什么,所以当你 运行 相同的代码两次时,我无法自己尝试,所以很难说出发生了什么。

关于你在 运行 上的评论,for 循环多次广告得到相同的 id...这可能不是 copy.copy 的问题,因为它复制顶级对象和 id 的顶级可变对象应该不同,但 id 的内部可变对象将保持不变,不像 copy.deepcopy 所有可变对象 id 应该不同。

可能是 __import__ 本身的问题...

当您在 Python 中导入模块时,它只会导入一次。因此,当您发出模块的第一次导入时 'some_module_a.py' 它被导入,然后,当您发出同一模块的第二次导入时 'some_module_a.py' 它不会再次导入,而是对已导入模块的引用是 reused/returned.

因此,如果您需要多次重新导入同一模块,请在第一次导入它,然后使用 importlib.reload 再次真正导入它。