import sys; sys.modules['_pickle'] = None import pickle from copy import copy class Graph: def __init__(self): self.vertices = {} self.edges = set() def __repr__(self): return "\n".join(map(str, sorted(self.vertices, key=lambda v:v.id))) def edges_add(self, edge): self.edges.add(edge) class Edge: def __init__(self, vfrom, vto): self.vfrom = vfrom self.vto = vto def __hash__(self): return hash((self.vto, self.vfrom)) def __repr__(self): return str(self.vto.id) def __getstate__(self): vfrom = copy(self.vfrom) vfrom.del_outgoing(self) vto = copy(self.vto) vto.del_incoming(self) self.__dict__.update({"vfrom":vfrom, "vto":vto, }) return self.__dict__ def __setstate__(self, state): self.__dict__.update(state) self.__dict__["vfrom"].add_outgoing(self) self.__dict__["vto"].add_incoming(self) class Vertex: def __init__(self, id): self.id = id self.incoming = set() self.outgoing = set() def __repr__(self): return "Vertex %d -> %s"%(self.id, ", ".join(map(str, self.outgoing))) def __hash__(self): return hash(self.id) def add_incoming(self, edge): if not edge in self.incoming: self.incoming.add(edge) def add_outgoing(self, edge): if not edge in self.outgoing: self.outgoing.add(edge) def del_incoming(self, edge): self.incoming.discard(edge) def del_outgoing(self, edge): self.outgoing.discard(edge) if __name__ == '__main__': v0 = Vertex(0) v1 = Vertex(1) e0to1 = Edge(v0, v1) v0.add_outgoing(e0to1) v1.add_incoming(e0to1) g = Graph() g.vertices[v0] = v0 g.vertices[v1] = v1 g.edges_add(e0to1) g.edges_add(e0to1) v2 = Vertex(2) e0to2 = Edge(v0, v2) v0.add_outgoing(e0to2) v2.add_incoming(e0to2) g.vertices[v2] = v2 g.edges_add(e0to2) print(g) p = pickle.dumps(g) print(pickle.loads(p))