方法比较Python字典与某些值类型失败?

方法比较Python字典与某些值类型失败?,python,dictionary,set,Python,Dictionary,Set,我想不出来。我有两本相同的词典。我使用一种标准方法来确定差异,其中不应有任何差异。但某些值类型总是作为差异返回,即使它们不是。例如,如果一个值是一个pymongo.bson.ObjectId,则该方法将无法对其进行相同的计算 d1 = {'Name':'foo','ref1':ObjectId('502e232ca7919d27990001e4')} d2 = {'Name':'foo','ref1':ObjectId('502e232ca7919d27990001e4')} d1 == d

我想不出来。我有两本相同的词典。我使用一种标准方法来确定差异,其中不应有任何差异。但某些值类型总是作为差异返回,即使它们不是。例如,如果一个值是一个
pymongo.bson.ObjectId
,则该方法将无法对其进行相同的计算

d1 = {'Name':'foo','ref1':ObjectId('502e232ca7919d27990001e4')}

d2 = {'Name':'foo','ref1':ObjectId('502e232ca7919d27990001e4')}

d1 == d2
返回:

True
set([('ref1',Objectid('502e232ca7919d27990001e4'))])
但是:

返回:

True
set([('ref1',Objectid('502e232ca7919d27990001e4'))])
所以我发现这很奇怪,不是吗

d1['ref1'] == d2['ref1']  # True

d1['ref1'] != d2['ref1']  # False
到底是什么

ObjectId('502e232ca7919d27990001e4')
创建一个新对象,默认情况下
=比较引用。例如:

class Obj:
    def __init__(self, value):
        self.value = value

print Obj(1234) == Obj(1234) # False
这将计算为false,因为它们是不同的实例,即使它们具有相同的值。为了实现这一点,该类必须实现eq方法:

class Obj:
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
        return self.value == other.value

print Obj(1234) == Obj(1234) # True
要解决此问题,您可以“monkey patch”类:

class Obj:
    def __init__(self, value):
        self.value = value

print Obj(1234) == Obj(1234) # False

Obj.__eq__ = lambda a, b: a.value == b.value

print Obj(1234) == Obj(1234) # True
或者直接用它们的值进行比较

print Obj(1234).value == Obj(1234).value

尽可能比较这些值,因为猴子补丁可能会破坏看似不相关的代码。

您的两个
ObjectId
值是引用同一个对象,还是不同的对象?
ObjectId
类是否适当地实现了
\uuuuuuuuuuuuuuuuuuuuuuu
?我试图用一个虚拟的
ObjectId
进行复制,但我得到了预期的结果(一个空集)。这是一个很好的问题,因为根据“映射(字典)比较相等,当且仅当它们的排序(键、值)列表比较相等。”因此
d1==d2
应该暗示
d1[k]==d2[k]
。有可能
ObjectId
是一个有缺陷的类,其中
hash(o)
基于,例如
o.value
,但
o1==o2
不是。但如果相等和散列都不是基于值的,那么这是完全合理的行为。@Blckknght相同的对象<代码>\uuuu eq\uuuu
已签出,但
id
并不感谢所有人,也为所有的花言巧语感到抱歉。。在这种情况下,这是一个bug,您应该添加一个
\uuuuuhash\uuuuuu
方法gauaranted,以便为相等的对象返回相同的值,例如
def\uuuuuuhash\uuuuuuuuuuuuuuuuuo(self):return hash(self.value)
,以防止问题中的行为发生。谢谢,您让我进入了测试模式,帮助我找到了bug