我认为像cryset和tuple这样的不可变类型实际上并没有被复制。这个叫什么?它有任何影响吗?

时间:2016-05-08 14:32:34

标签: python python-3.x

我在试图弄清楚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'])

1 个答案:

答案 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