I will get straight to the example that made me ask such a question:
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
As per the documentation of deepcopy, I was expecting the last line to have False as a response, i.e. that deepcopy would also clone the string.
Thanks in advance
At least in CPython, the ID points to the object address in memory. Because Python strings are immutable, deepcopy
won't create a different ID. There's really no need to create a different string in memory to hold the exact same data.
The same happens for tuples that only hold immutable objects, for example:
>>> from copy import deepcopy
>>> a = (1, -1)
>>> b = deepcopy(a)
>>> id(a) == id(b)
True
If you tuple holds mutable objets, that won't happen:
>>> a = (1, [])
>>> b = deepcopy(a)
>>> id(a) == id(b)
False
So in the end the answer is: deepcopy
is working just fine for your classes, you just found a gotcha about copying immutable objects.