我有兩個自定義對象在其中。我從一組中獲取對象,並使用set.update將它們添加到另一組中。蟒蛇集似乎持有兩個相同的對象
之後,似乎一組包含兩個相同的對象:他們的哈希值是相同的,他們==對方,而不是=對方!如果我將該集合轉換爲列表並返回到集合,那麼在新集合中只有一個對象。我沒有其他線程或進程正在運行,這可能會突然改變中間任何對象的狀態。
我可以張貼我的哈希和EQ但他們調用多個其他子對象哈希和EQ,這將是大量的代碼,包括。
相反這裏是調試代碼我運行它的輸出:
print('old hash', map(hash, node.incoming_edges))
print('new hash', map(hash, new_node.incoming_edges))
if len(new_node.incoming_edges) > 1:
node1, node2 = list(new_node.incoming_edges)
print('eq', node1 == node2)
print('ne', node1 != node2)
print('type', type(node.incoming_edges))
print('type', type(new_node.incoming_edges))
new_node.incoming_edges.update(node.incoming_edges)
print('combined')
if len(new_node.incoming_edges) > 1:
node1, node2 = list(new_node.incoming_edges)
print('eq', node1 == node2)
print('ne', node1 != node2)
print('combined hash', map(hash, new_node.incoming_edges))
print('len', len(new_node.incoming_edges))
new_node.incoming_edges = set(list(new_node.incoming_edges))
print('len', len(new_node.incoming_edges))
和相關的輸出:
old hash [5805087492197093178]
new hash [5805087492197093178]
type <type 'set'>
type <type 'set'>
combined
eq True
ne False
combined hash [5805087492197093178, 5805087492197093178]
len 2
len 1
我在想,既然我的對象是遞歸的圖表,哈希可能通過將它們添加到集合中進行更改,但是我在操作之前和之後打印哈希以確認哈希值未發生更改。
這怎麼可能發生?我很樂意介紹更多的調試輸出,我可以很容易地重現。
P.S.下面是從PDB一些信息,而我試圖瞭解發生了什麼:
57 print('type', type(new_node.incoming_edges))
58
59 import pdb; pdb.set_trace()
60
61 new_node.incoming_edges.update(node.incoming_edges)
62 -> new_node.outgoing_edges.update(node.outgoing_edges)
63 # new_node.incoming_edges = set(list(new_node.incoming_edges))
64
65 print('combined')
66 if len(new_node.incoming_edges) > 1:
67 node1, node2 = list(new_node.incoming_edges)
(Pdb) !len(new_node.incoming_edges)
2
(Pdb) !x, y = new_node.incoming_edges
(Pdb) x
<Edge user.id getters={<SQLQuery tables:users; selects:users.last_name; where:{} input_mapping:{'id': 'users.id'}, <SQLQuery tables:users; selects:users.first_name; where:{} input_mapping:{'id': 'users.id'}} setter=None out=False>
(Pdb) y
<Edge user.id getters={<SQLQuery tables:users; selects:users.last_name; where:{} input_mapping:{'id': 'users.id'}, <SQLQuery tables:users; selects:users.first_name; where:{} input_mapping:{'id': 'users.id'}} setter=None out=False>
(Pdb) hash(x)
-8545778292158950550
(Pdb) hash(y)
-8545778292158950550
(Pdb) x == y
True
(Pdb) x != y
False
(Pdb) len(set(list(new_node.incoming_edges)))
1
(Pdb) len(new_node.incoming_edges)
2
你說可以發佈您的'__hash__'和'__eq__'將是一個很大的,因爲他們最終確認了大量的子對象。涉及哪些子對象檢查?特別是,你是否在可變對象上進行任何'=='比較,比如邊緣端點? – user2357112
你的例子有些東西不在這裏。這是蟒蛇3嗎?不能,你的'打印'將打印'地圖'對象,而不是列表。這是蟒蛇2嗎?不能,你的'打印'將打印元組。 – roippi