Python集合\uuuu contains\uuuu未找到集合中包含的对象

Python集合\uuuu contains\uuuu未找到集合中包含的对象,python,set,contains,Python,Set,Contains,(linux上的python 3.7.1) 我观察到一些奇怪的行为,将用户定义的对象存储在一个集合中。这些对象非常复杂,因此不可能有一个简单的例子——但我希望观察到的行为能从比我更聪明的人那里得到解释。这是: >>> from mycode import MyObject >>> a = MyObject(*args1) >>> b = MyObject(*args2) >>> a == b False >>&g

(linux上的python 3.7.1)

我观察到一些奇怪的行为,将用户定义的对象存储在一个集合中。这些对象非常复杂,因此不可能有一个简单的例子——但我希望观察到的行为能从比我更聪明的人那里得到解释。这是:

>>> from mycode import MyObject
>>> a = MyObject(*args1)
>>> b = MyObject(*args2)
>>> a == b
False
>>> z = {a, b}
>>> len(z)
2
>>> a in z
False
我的理解是,如果(1)一个对象的哈希值与集合中某个对象的哈希值匹配,并且(2)它等于该对象,那么该对象就是集合中的。但这些期望在这里被违背了:

>>> [hash(t) for t in z]
[1013724486348463466, -1852733432963649245]
>>> hash(a)
1013724486348463466
>>> [(hash(t) == hash(a), t == a) for t in z]
[(True, True), (False, False)]
>>> [t is a for t in z]
[True, False]
还有最奇怪的(语法上的):

MyObject
有什么可能导致它这样做?概括地说:它有一个健全的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

具体如下:

class MyObject(object):
    ...
        def __hash__(self):
            return hash(self.link)

        def __eq__(self, other):
            """
            two entities are equal if their types, origins, and external references are the same.
            internal refs do not need to be equal; reference entities do not need to be equal
            :return:
            """
            if other is None:
                return False
            try:
                is_eq = (self.external_ref == other.external_ref
                         and self.origin == other.origin
                         and self.entity_type == other.entity_type)
            except AttributeError:
                is_eq = False
            return is_eq

所有这些特性都是在这些对象上定义的。如上所示,
a==t
对于集合中的一个对象计算为
True
。谢谢你的建议。

在将对象添加到集合后,我对它们进行了变异。定义的哈希函数不是静态的。

我想说您得到的是
除了AttributeError之外的
,因为其中一个成员没有定义。你能发布你的物品的代码吗?当到达
AttributeError
时尝试打印消息在比较
self.external\u ref
等时是否有可疑之处?我打赌在将对象添加到集合后,您会对其进行变异。而且
\uuuuuuuu hash\uuuuu
\uuuuuuuuu eq\uuu
正在查看完全不相交的对象集也是没有意义的但即使散列是假的,这也不会阻止set工作。我们需要一份工作。你的班级太大了?把它减少一点
class MyObject(object):
    ...
        def __hash__(self):
            return hash(self.link)

        def __eq__(self, other):
            """
            two entities are equal if their types, origins, and external references are the same.
            internal refs do not need to be equal; reference entities do not need to be equal
            :return:
            """
            if other is None:
                return False
            try:
                is_eq = (self.external_ref == other.external_ref
                         and self.origin == other.origin
                         and self.entity_type == other.entity_type)
            except AttributeError:
                is_eq = False
            return is_eq