我正在使用python3和networkx来构建图形。 Networkx真的很棒,但是我想说我想把一些好的对象放在节点中。这是我的对象制作者(一个简单的类,为了演示目的):
class DictToObject:
def __init__(self, dic):
for key, value in dic.items():
setattr(self, key, value)
def __eq__(self, other):
return self.id == other.id
然后是一些节点:
import networkx
s1 = DictToObject({"name":"sarah", "id":"s"})
s2 = DictToObject({"name":"sarah", "id":"s"})
M = networkx.DiGraph()
M.add_edge(s1, s2)
由于覆盖__eq__
,我收到错误:
Traceback (most recent call last):
File "networkxcapabilitytest.py", line 16, in <module>
M.add_edge(s1, s2)
File "/usr/local/lib/python3.4/site-packages/networkx/classes/digraph.py", line 485, in add_edge
if u not in self.succ:
TypeError: unhashable type: 'DictToObject'
这令人非常沮丧。覆盖__eq__
似乎是让networkx识别何时应将两个节点视为“相同”的“正确”方法。也许我应该将此问题提交给networkx开发人员。或者也许有一个内置的networkx或更好的方法。
答案 0 :(得分:1)
关注@ jonrsharpe的评论:
class DictToObject:
def __init__(self, dic):
for key, value in dic.items():
setattr(self, key, value)
def __eq__(self, other):
return self.id == other.id
def __hash__(self):
return hash(self.__dict__.values())
def __repr__(self):
return str(self.__dict__.values())
import networkx
s1 = DictToObject({"name":"sarah", "id":"s"})
s2 = DictToObject({"name":"sarah", "id":"s"})
M = networkx.DiGraph()
M.add_edge(s1, s2)
print( M.nodes() )
print( M.edges() )
输出:
[dict_values(['s', 'sarah'])]
[(dict_values(['s', 'sarah']), dict_values(['s', 'sarah']))]
请注意,现在图表中只有一个节点。由于hash()
生成(id&#39; s)相同的东西,因此它不会将第二个节点添加到图中。