我正在尝试腌制一个包含另一个实例的两个列表的类实例。两个列表中的实例具有引用彼此实例的属性。这是课程。
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)))
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)
当我如下腌制一个简单的图表时,我得到了一个 AssertionError。
>>> 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
Vertex 0 -> 2, 1
Vertex 1 ->
Vertex 2 ->
>>> p = pickle.dumps(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/pickle.py", line 1366, in dumps
Pickler(file, protocol).dump(obj)
File "/usr/lib/python2.6/pickle.py", line 224, in dump
self.save(obj)
File "/usr/lib/python2.6/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.6/pickle.py", line 725, in save_inst
save(stuff)
File "/usr/lib/python2.6/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.6/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/usr/lib/python2.6/pickle.py", line 663, in _batch_setitems
save(v)
File "/usr/lib/python2.6/pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "/usr/lib/python2.6/pickle.py", line 401, in save_reduce
save(args)
File "/usr/lib/python2.6/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.6/pickle.py", line 562, in save_tuple
save(element)
File "/usr/lib/python2.6/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.6/pickle.py", line 600, in save_list
self._batch_appends(iter(obj))
File "/usr/lib/python2.6/pickle.py", line 615, in _batch_appends
save(x)
File "/usr/lib/python2.6/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.6/pickle.py", line 725, in save_inst
save(stuff)
File "/usr/lib/python2.6/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.6/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/usr/lib/python2.6/pickle.py", line 663, in _batch_setitems
save(v)
File "/usr/lib/python2.6/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.6/pickle.py", line 725, in save_inst
save(stuff)
File "/usr/lib/python2.6/pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "/usr/lib/python2.6/pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "/usr/lib/python2.6/pickle.py", line 663, in _batch_setitems
save(v)
File "/usr/lib/python2.6/pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "/usr/lib/python2.6/pickle.py", line 405, in save_reduce
self.memoize(obj)
File "/usr/lib/python2.6/pickle.py", line 244, in memoize
assert id(obj) not in self.memo
AssertionError
我在删除 v2 时工作。
>>> v0 = Vertex(0)
>>> v1 = Vertex(1)
>>> e0to1 = Edge(v0, v1)
>>> v0.outgoing.add(e0to1)
>>> v1.incoming.add(e0to1)
>>> g = Graph()
>>> g.vertices[v0] = v0
>>> g.vertices[v1] = v1
>>> g.edges.add(e0to1)
>>> g.edges.add(e0to1)
>>> import cPickle as pickle
>>> p = pickle.dumps(g)
>>> print pickle.loads(p)
Vertex 0 -> 1
Vertex 1 ->
你有什么主意吗?