我在试图弄清楚Python中的浅层和深层复制时一直在搞乱,并注意到虽然复制集,列表或看似任何可变类型的身份都不相同:
In[2]: x1 = {1,2,3}
In[3]: x2 = x1.copy()
In[4]: x1 is x2
Out[4]: False
对于不可变类型,情况并非如此 - 它看起来像是指向内存中相同地址的副本。
In[6]: f1 = frozenset({1,2,3})
In[7]: f2 = f1.copy()
In[8]: f1 is f2
Out[8]: True
这种直觉对我有意义 - 为什么你还需要两个相同的不可变对象。但我以前从未见过它 - 这个过程有没有名字?这是为了速度目的吗?
此外,这种“非实际复制”是否有任何影响?我不相信有,但我想确定 - 我唯一想到的就是有人决定修改一个不可变类型中的可变类型,从我所知的反正是一个坏主意。
In[11]: t1 = tuple((1, ['a', 'b']))
In[12]: t2 = tuple(t1) # I would expect an actual copy, but it is not
In[13]: t1[1].append('c')
In[14]: t2
Out[14]: (1, ['a', 'b', 'c'])
答案 0 :(得分:5)
它被称为polymorphism。
不同类型可以实现__copy__()
和__deepcopy__()
挂钩,并执行与其类型有意义的不同操作。 copy
module只是调用这些挂钩来委派实际的复制工作(或者在设置类型的情况下,委托给set.copy()
方法)。然后,不可变类型可以自由返回self
以避免浪费内存。
否则,对于不可变类型,self
从__copy__()
返回list(some_list_object)
的选择没有特殊名称。
请注意,对于带有元组的元组示例,您只需要浅拷贝。容器的浅拷贝总是重复使用对内容的引用。 dict(some_dict_object)
或>>> import copy
>>> t1 = (1, ['a', 'b'])
>>> t2 = copy.deepcopy(t1)
>>> t1 is t2
False
>>> t1[0].append('c')
>>> t2
(1, ['a', 'b'])
会发生同样的事情。使用深层复制来确保您获得包含所包含列表副本的元组;然后创建一个新的元组对象:
Thread