2011-07-25 49 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。第三个元素,一个不可变的字符串,不会被复制。