python deepcopy 没有深度复制用户 类?
python deepcopy not deepcopying user classes?
我将直接进入让我提出这样一个问题的例子:
Python 3.6.6 (default, Jul 19 2018, 14:25:17)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from copy import deepcopy
In [2]: class Container:
...: def __init__(self, x):
...: self.x = x
...:
In [3]: anobj = Container("something")
In [4]: outobj = Container(anobj)
In [5]: copy = deepcopy(outobj)
In [6]: id(copy) == id(outobj)
Out[6]: False
In [7]: id(copy.x) == id(outobj.x)
Out[7]: False
In [8]: id(copy.x.x) == id(outobj.x.x)
Out[8]: True
根据 deepcopy 的文档,我希望最后一行有 False 作为响应,即 deepcopy 也会克隆字符串。
- 为什么不是这样?
- 如何获得所需的行为?我的原始代码具有不同级别的嵌套自定义 类,具有预定义类型的 "final" 属性。
提前致谢
At least in CPython,ID指向内存中的对象地址。因为 Python 字符串是不可变的,所以 deepcopy
不会创建不同的 ID。确实不需要在内存中创建不同的字符串来保存完全相同的数据。
只包含不可变对象的元组也是如此,例如:
>>> from copy import deepcopy
>>> a = (1, -1)
>>> b = deepcopy(a)
>>> id(a) == id(b)
True
如果元组包含可变对象,则不会发生这种情况:
>>> a = (1, [])
>>> b = deepcopy(a)
>>> id(a) == id(b)
False
所以最后的答案是:deepcopy
对你的 类 工作得很好,你只是发现了一个关于复制不可变对象的 陷阱 。
我将直接进入让我提出这样一个问题的例子:
Python 3.6.6 (default, Jul 19 2018, 14:25:17)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from copy import deepcopy
In [2]: class Container:
...: def __init__(self, x):
...: self.x = x
...:
In [3]: anobj = Container("something")
In [4]: outobj = Container(anobj)
In [5]: copy = deepcopy(outobj)
In [6]: id(copy) == id(outobj)
Out[6]: False
In [7]: id(copy.x) == id(outobj.x)
Out[7]: False
In [8]: id(copy.x.x) == id(outobj.x.x)
Out[8]: True
根据 deepcopy 的文档,我希望最后一行有 False 作为响应,即 deepcopy 也会克隆字符串。
- 为什么不是这样?
- 如何获得所需的行为?我的原始代码具有不同级别的嵌套自定义 类,具有预定义类型的 "final" 属性。
提前致谢
At least in CPython,ID指向内存中的对象地址。因为 Python 字符串是不可变的,所以 deepcopy
不会创建不同的 ID。确实不需要在内存中创建不同的字符串来保存完全相同的数据。
只包含不可变对象的元组也是如此,例如:
>>> from copy import deepcopy
>>> a = (1, -1)
>>> b = deepcopy(a)
>>> id(a) == id(b)
True
如果元组包含可变对象,则不会发生这种情况:
>>> a = (1, [])
>>> b = deepcopy(a)
>>> id(a) == id(b)
False
所以最后的答案是:deepcopy
对你的 类 工作得很好,你只是发现了一个关于复制不可变对象的 陷阱 。