I\'m trying to use deepcopy on an ndarray, and the line looks like this:
foo = myArray.__deepcopy__()
I\'m getting:
TypeErr
The copy module contains the documentation for __deepcopy__
, and it is quite clear what the argument should be:
In order for a class to define its own copy implementation, it can define special methods
__copy__()
and__deepcopy__()
. The former is called to implement the shallow copy operation; no additional arguments are passed. The latter is called to implement the deep copy operation; it is passed one argument, the memo dictionary.
But if you're not implementing a customized deep-copyable class you generally don't need to bother about this, simply use copy.deepcopy
:
from copy import deepcopy
import numpy as np
arr = np.random.random((100, 100))
deepcopy(arr)
It will take care of the memo
-dict without your intervention. Note: Most of the __*__
are designed that way, you generally don't and shouldn't call them directly. So like you use x in y
instead of y.__contains__(x)
you normally use copy.deepcopy(x)
instead of x.__deepcopy__(dict())
.
The relevant code in copy
is:
def deepcopy(x, memo=None, _nil=[]):
"""Deep copy operation on arbitrary Python objects.
See the module's __doc__ string for more info.
"""
if memo is None:
memo = {}
....
copier = getattr(x, "__deepcopy__", None)
if copier:
y = copier(memo)
...
# If is its own copy, don't memoize.
if y is not x:
memo[d] = y
_keep_alive(x, memo) # Make sure x lives at least as long as d
return y
So memo
is a memoize
dictionary, at least when used 'properly'
So if I pass a dictionary as memo
, it changes that:
In [160]: dd={}
In [161]: A2=copy.deepcopy(A,memo=dd)
In [162]: dd
Out[162]:
{2814755008: array([[[0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 1],
[0, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 1, 0]],
[[0, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]]]), 2814808588: [array([[[0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 1],
[0, 0, 0, 1, 0, 1],
[1, 0, 0, 0, 1, 0]],
[[0, 0, 1, 0, 0, 0],
[0, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]]])]}
In [163]: id(A)
Out[163]: 2814755008
In [167]: id(dd[id(A)])
Out[167]: 2814568472
In [168]: id(A2)
Out[168]: 2814568472
The memo
keeps a record of the copy. I don't know what the 2nd item is.
And if I ask for another deep copy with the same memo, it gives the memoized array rather than a new copy.
In [173]: A3=copy.deepcopy(A,memo=dd)
In [174]: id(A2)
Out[174]: 2814568472
In [175]: id(A3)
Out[175]: 2814568472
If an array is object dtype, the deepcopy
might make a difference. The memo certainly looks different.
The special __deepcopy__
method takes a memo
arg. You can pass an empty dict for this:
foo = myArray.__deepcopy__({})