Is it posible to only deep copy a certain types of object, such as a list, a dict, or a tuple
Example: [[1, <SomeObj>], <OtherObj>]
I want to deep copy the first list (and of course.. the 1), but not SomeObj
or OtherObj
. Those should stay as refereces.
Is that possible to do that with some function that i'm not familiar with or do i have to write my own function?...
You can do it with copy.deepcopy
pretty easily by overriding the __deepcopy__
method in each of the classes you need it in. If you want different copying behavior depending on the situation, you can just set the __deepcopy__
function at runtime and then reset it:
import copy
class OtherObject(object):
pass
l = [[1, 2, 3], [4, 5, 6], OtherObject()]
# first, save the old deepcopy if there is one
old_deepcopy = None
if hasattr(OtherObject, __deepcopy__):
old_deepcopy = OtherObject.__deepcopy__
# do a shallow copy instead of deepcopy
OtherObject.__deepcopy__ = lambda self, memo: self
l2 = copy.deepcopy(l)
# and now you can replace the original behavior
if old_deepcopy is not None:
OtherObject.__deepcopy__ = old_deepcopy
else:
del OtherObject.__deepcopy__
>>> l[0] is l2[0]
False
>>> l[1] is l2[1]
False
>>> l[2] is l2[2]
True
As far as I know, there's no utility to do that. The built-ins copy
and deepcopy
require that objects provide their own __copy__
and __deepcopy__
methods to override the default behavior. Which is not a good idea IMHO, since you don't always want the same kind of copies...
Writing a function to do that shouldn't be hard, though. Here's an example that works for lists, tuples and dicts:
def mycopy(obj):
if isinstance(obj, list):
return [mycopy(i) for i in obj]
if isinstance(obj, tuple):
return tuple(mycopy(i) for i in obj)
if isinstance(obj, dict):
return dict(mycopy(i) for i in obj.iteritems())
return obj
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With