2016-02-28 64 views
1

我想了解一个观察。 我有一个应用程序,加载用户以后可以使用的各种类型的Canvas类。这些类位于几个文件中。例如, 。为什么复制的对象与以前在Python中复制的对象具有相同的ID?

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中更改设置时,它们会在复制的设备中自动更改。

为什么会发生这种情况,我做错了什么?

+0

您能否提供一个独立的示例来显示重复的对象? – BrenBarn

+0

我只是想知道我的逻辑是否正确。 – minerals

回答

1

仅使用copy.copy()创建浅拷贝。当使用copy.deepcopy()复制对象时,您可能希望使用深度复制。

您可以详细阅读什么是这里的区别:https://docs.python.org/2/library/copy.html

我不知道是什么canv.Canvas()做里面,因此很难说这是怎么回事,当你运行相同的代码上两次当我不能尝试我自己。

+0

是的,我知道区别,只是无法理解为什么id是相同的。那么,通过'deepcopy'它有点不错,为什么呢,这是一个更全面的问题。 – minerals

0

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

1

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

也许这是一个与__import__本身的问题...

当你在Python导入模块,它的进口只有一次。因此,当您发出模块'some_module_a.py'的第一次导入时,它会被导入,然后当您再次导入相同模块'some_module_a.py'时,它不会再次导入,但是对已导入模块的引用被重用/返回。

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