AttributeError: Edge实例没有属性'vto

4 投票
1 回答
1129 浏览
提问于 2025-04-16 08:26

我正在尝试把一个包含两个列表的类实例进行序列化,这两个列表里又包含其他实例。这些实例之间有属性是相互引用的。以下是这些类的代码。

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(tuple(map(hash, (self.vto, self.vfrom))))
    def __repr__(self):
        return str(self.vto.id)

class Vertax:
    def __init__(self, id):
        self.id = id
        self.incoming = set()
        self.outgoing = set()
    def __repr__(self):
        return "Vertax %d -> %s"%(self.id, ", ".join(map(str, self.outgoing)))
    def __hash__(self):
        return hash(self.id)

当我尝试序列化一个简单的图时,反序列化时出现了错误。

>>> v0 = Vertax(0)
>>> v1 = Vertax(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)
>>> print g
Vertax 0 -> 1
Vertax 1 -> 
>>> 
>>> import pickle
>>> p = pickle.dumps(g)
>>> pickle.loads(p)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/pickle.py", line 1374, in loads
    return Unpickler(file).load()
  File "/usr/lib/python2.6/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib/python2.6/pickle.py", line 1133, in load_reduce
    value = func(*args)
  File "<stdin>", line 6, in __hash__
AttributeError: Edge instance has no attribute 'vto'

我发现如果把边类(Edge class)里的__hash__函数注释掉,错误就消失了。我需要你帮我理解这是为什么。

1 个回答

3

这个Python的问题可能是因为这个链接里的内容引起的:http://bugs.python.org/issue1761028

“pickle - 不能反序列化有循环依赖的自定义 __hash__

撰写回答