2016-02-28 49 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再次導入它。