Python set __contains__ 未找到集合中包含的对象
Python set __contains__ is not finding objects contained in the set
(python linux 上的 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
我的理解是,一个对象是 "in" 一个集合,如果 (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]
最奇怪的(语法上):
>>> [t in z for t in z]
[False, False]
MyObject
是什么原因导致它出现这种行为?回顾一下:它有一个正常的 __hash__
和 __eq__
功能,set
只是一个股票 python 集。
具体如下:
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
。感谢您的任何建议。
我在将对象添加到集合后对其进行了变异。定义的哈希函数不是静态的。
(python linux 上的 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
我的理解是,一个对象是 "in" 一个集合,如果 (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]
最奇怪的(语法上):
>>> [t in z for t in z]
[False, False]
MyObject
是什么原因导致它出现这种行为?回顾一下:它有一个正常的 __hash__
和 __eq__
功能,set
只是一个股票 python 集。
具体如下:
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
。感谢您的任何建议。
我在将对象添加到集合后对其进行了变异。定义的哈希函数不是静态的。