python pickle.dumps 断言错误

标签 python pickle cross-reference

我正在尝试 pickle 包含两个其他实例列表的类实例。两个列表中的实例具有相互引用实例的属性。这是类。

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)

当我按如下方式 pickle 一个简单的图表时,我得到了一个 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 -> 

你有什么想法吗?

最佳答案

旧的 pickle 协议(protocol)无法处理某些类型的数据。要解决您的问题,请使用 pickle.HIGHEST_PROTOCOL

>>> p = pickle.dumps(g)
  File "/usr/lib/python2.6/pickle.py", line 244, in memoize
    assert id(obj) not in self.memo
AssertionError:
>>> p = pickle.dumps(g, pickle.HIGHEST_PROTOCOL)
>>> # No problem!

关于python pickle.dumps 断言错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4426981/

相关文章:

python - 搜索大tar.gz文件中的关键字,复制并删除

python - python doctest 可以忽略一些输出行吗?

python - 导入错误 : cannot import name 'show_config'

python - 如何更改多处理模块使用的序列化方法?

documentation - Documenter.jl 中其他子模块的交叉引用函数

css - 如何去除sphinx文档中对内部超链接的强调

amazon-web-services - cloudFormation 模板验证错误 : how to split serverless. yml 文件

Python-UnboundLocalError : local variable referenced before assignment - Regular Expressions/if else

tensorflow - 如何在 tensorflow 中将 TextVectorization 保存到磁盘?

python - 使用 python 和多处理压缩输出