【问题标题】:Python set __contains__ is not finding objects contained in the set [closed]Python set __contains__ 没有找到集合中包含的对象[关闭]
【发布时间】:2018-12-07 22:45:22
【问题描述】:

(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]

还有最奇怪的(语法上):

>>> [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。感谢您的任何建议。

【问题讨论】:

  • 我会说你得到except AttributeError 因为其中一个成员没有被定义。你可以发布你的对象的代码吗?到达AttributeError 时尝试打印消息
  • self.external_ref 等的比较会不会有什么可疑之处?
  • 我敢打赌,在将对象添加到集合后,您会变异对象。
  • 另外,__hash____eq__ 正在查看完全不相交的属性集是没有意义的。
  • 但即使 hash 是伪造的,也不会阻止 set 工作。我们需要一个minimal reproducible example。你的班级太大了?将其缩小为minimal reproducible example

标签: python set contains


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    • 2014-03-20
    • 2011-12-15
    • 2022-10-23
    • 1970-01-01
    相关资源
    最近更新 更多