Python deepcopy .. view

Is it possible to only deep copy certain types of objects, such as a list, dict or tuple

Example: [[1, <SomeObj>], <OtherObj>]

I want to copy the first list (and, of course, 1), but not SomeObj or OtherObj . Those must remain as referees.

Is it possible to do this with some function that I am not familiar with or do I need to write my own function? ...

+4
source share
3 answers

As far as I know, there is no utility for this. The built-in copy and deepcopy require objects to provide their __copy__ and __deepcopy__ to override the default behavior. Which is not a good idea IMHO, since you do not always want to have copies of the same type ...

Writing a function for this should not be complicated. Here is 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 
+3
source

You can do this with copy.deepcopy quite easily by overriding the __deepcopy__ method in each of the classes you need. If you need a different copy behavior depending on the situation, you can simply 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 
+4
source

I don’t know about any python tool that will make deep copies of only the base types and save other elements as links.

I think you should write a small recursive function for this (less than 20 lines).

+1
source

Source: https://habr.com/ru/post/1390949/


All Articles