I have a graph data structure Overlay
, which consists of instances that are interconnected by edges. Instances are represented by a set of Instance
-objects and edges are represented by a set of Edge
-objects.
For convenience, each instance keeps track of the in- and outgoing edges by pointing to the corresponding existing Edge
-objects. Similarly, each edge points to the source- and the destination-Instance
-object.
For example, an overlay may consist of an instance i1
that is connected to another instance i2
via an edge e1
. e1.source
is a reference to i1
and e2.dest
is a reference to i2
. i1.edges_out
contains a reference to e1
, etc. Overall, there are just 2 Instance
-objects and 1 Edge
-object.
I want to deep copy an overlay, in order to modify it (its instances and edges) without affecting the other overlay(s). My problem is that I don't know how to preserve the structure of interconnecting references as described above.
I use new_overlay = copy.deepcopy(old_overlay)
and override __deepcopy__
in Overlay
, Instance
, and Edge
as follows:
In Overlay
:
def __deepcopy__(self, memodict={}):
new_overlay = Overlay(self.template, set(), set()) # new, empty overlay
new_overlay.instances = copy.deepcopy(self.instances, memodict)
new_overlay.edges = copy.deepcopy(self.edges, memodict)
return new_overlay
In Instance
:
def __deepcopy__(self, memodict={}):
# new instance with same attributes
new_instance = Instance(self.attributes)
# edges_in, _out should contain references to the existing edges, not new objects
new_instance.edges_in = copy.deepcopy(self.edges_in, memodict)
new_instance.edges_out = copy.deepcopy(self.edges_out, memodict)
return new_instance
In Edge
:
def __deepcopy__(self, memodict={}):
# new edge with same source and destination: these should be references to existing instances, not new objects
new_edge = Edge(copy.deepcopy(self.source, memodict), copy.deepcopy(self.dest, memodict))
new_instance.attribute = self.attribute # no need to deep copy
return new_edge
I was hoping for copy.deepcopy
to take care of everything by using the memodict
, but it doesn't work: When checking the object-id
with the PyCharm debugger, the references in the copied overlay are sometimes incorrect. Instead of referencing existing objects, e.g., existing instances as source/destination of an edge, new instance objects are created.
How can I deep copy Overlay
while preserving the structure of references? Both edges should have references to instances (source/destination) and instances should have references to edges (edges_in/edges_out).