2011-07-25 50 views
5

我不知道python解釋器在對可變對象執行深度拷貝時是否在寫入策略上應用了拷貝。深度複製是否使用寫入時複製?

另外,我想知道,如果也進行nonmutable對象的deepcopy的(這似乎但是很奇怪,我)

回答

5

它不會進行寫入時複製。

它不會對一些內置的不可變類型執行深層複製,但是任何用戶定義的「不可變」類型都將被深度複製。

copy.py in the Python 2.7 standard library包括在其文檔中這樣的信息:

此版本不復制類型,如模塊,類,函數,方法,也沒有堆棧跟蹤,堆棧幀,也不文件,插座,窗口,也不陣列,也沒有類似的類型。

copy處理不可變對象是這樣的:

def _copy_immutable(x): 
    return x 
for t in (type(None), int, long, float, bool, str, tuple, 
      frozenset, type, xrange, types.ClassType, 
      types.BuiltinFunctionType, type(Ellipsis), 
      types.FunctionType, weakref.ref): 
    d[t] = _copy_immutable 
for name in ("ComplexType", "UnicodeType", "CodeType"): 
    t = getattr(types, name, None) 
    if t is not None: 
     d[t] = _copy_immutable 

deepcopy採用了更復雜的方案,這就是太長複製到這個最,但要點是一樣的。有趣的一點是,_deepcopy_tuple迭代其元素,並且不會創建新對象,直到找到被複制的元素。

for i in range(len(x)): 
    if x[i] is not y[i]: 
     y = tuple(y) 
     break 
else: 
    y = x 
+0

+1提供該鏈接。 41-43行清楚地說明了什麼是複製的,哪些不是。 – Emiliano

+2

它似乎實際上比這更聰明:根據我的測試,'(1,[2,3])'將被複制,但'(1,(2,3))'不會。顯然,它看起來包含的類型以及容器。 – interjay

+0

@happy哈,我什至沒有注意到。我應該在答案中包括這一點。 –

4

不,不,只是拷貝的對象。如果它們引用mutable,它也必須複製不可變對象。

+1

啊我沒有考慮引用mutable的不可變對象。 +1。此外,這是否意味着,如果我發出2個模塊對象的深層拷貝,即使功能對象被複制(即我有2個相同的功能在內存中)? – Emiliano

+1

@happy_emi:函數未被複制。嘗試'deepcopy(deepcopy)是deepcopy'。 –

3

讓我們來看看:

>>> import copy 
>>> x = [[1],[2],"abc"] 
>>> y = copy.deepcopy(x) 
>>> id(x[0]) 
4299612960 
>>> id(y[0]) 
4299541608 
>>> id(x[2]) 
4297774504 
>>> id(y[2]) 
4297774504 

對於xy的第一要素,複製執行和對象有一個新的ID。第三個元素,一個不可變的字符串,不會被複制。