我在试图弄清楚Python中的浅层和深层复制时一直在搞乱,并注意到虽然复制的集合,列表或看似任何可变类型的身份都不相同:
In[2]: x1 = {1,2,3}
In[3]: x2 = x1.copy()
In[4]: x1 is x2
Out[4]: False
Run Code Online (Sandbox Code Playgroud)
对于不可变类型,情况并非如此 - 它看起来像是指向内存中相同地址的副本.
In[6]: f1 = frozenset({1,2,3})
In[7]: f2 = f1.copy()
In[8]: f1 is f2
Out[8]: True
Run Code Online (Sandbox Code Playgroud)
这种直觉对我来说很有意义 - 为什么你在内存中需要两个相同的不可变对象呢?但我以前从未见过它 - 这个过程有没有名字?这是为了速度目的吗?
此外,这种"非实际复制"是否有任何影响?我不相信有,但我想确定 - 我唯一想到的就是如果有人决定修改一个不可变类型中的可变类型,从我所知道的反正是一个坏主意.
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'])
Run Code Online (Sandbox Code Playgroud)
它被称为多态性.
不同的类型可以实现__copy__()和__deepcopy__()挂钩,并做一些与他们的类型有意义的不同的东西.该copy模块简单地调用这些钩子委派实际的复制工作(或一组类型的情况下,委托给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'])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
191 次 |
| 最近记录: |