Python 2:x27的不同含义;在';集合和列表的关键字

Python 2:x27的不同含义;在';集合和列表的关键字,python,list,set,equality,Python,List,Set,Equality,考虑一下这个片段: class SomeClass(object): def __init__(self, someattribute="somevalue"): self.someattribute = someattribute def __eq__(self, other): return self.someattribute == other.someattribute def __ne__(self, other):

考虑一下这个片段:

class SomeClass(object):

    def __init__(self, someattribute="somevalue"):
        self.someattribute = someattribute

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

    def __ne__(self, other):
        return not self.__eq__(other)

list_of_objects = [SomeClass()]
print(SomeClass() in list_of_objects)

set_of_objects = set([SomeClass()])
print(SomeClass() in set_of_objects)
评估结果如下:

True
False
有人能解释为什么“in”关键字对集合和列表有不同的含义吗?
我希望两者都返回True,特别是当被测试的类型定义了相等方法时。

含义相同,但实现不同。列表只是检查每个对象,检查是否相等,以便它适用于您的类。集合首先散列对象,如果它们没有正确实现散列,则集合似乎不起作用

您的类定义了
\uuuuu eq\uuuu
,但没有定义
\uuuu hash\uuuuuu
,因此不能正确地用于集合或作为字典的键。
\uuuuu eq\uuuu
\uuuu hash\uuuu
的规则是,两个
\uuuuu eq\uuuu
为True的对象的散列也必须相等。默认情况下,对象根据其内存地址散列。因此,根据您的定义相等的两个对象不提供相同的哈希,因此它们违反了关于
\uuuuueq\uuu
\uuuuuuhash\uuuu
的规则

如果您提供了一个
\uuuuuuuuuuuuuuuuuuuuuu散列
实现,它就可以正常工作。对于示例代码,它可以是:

def __hash__(self):
    return hash(self.someattribute)

定义与您的
\uuuuuueq\uuuuuu()方法相对应的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

在几乎所有的哈希表实现中,包括Python的,如果要覆盖相等方法,就必须覆盖哈希方法(在Python中,就是这样)。列表中的
操作符只检查列表中每个元素的相等性,而
中的
操作符首先对要查找的对象进行散列,检查哈希表的该插槽中的对象,然后检查插槽中是否存在相等性。因此,如果您在未重写
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
的情况下重写someattribute
这里是一个类属性而不是实例属性,对吗?你听说过
\uuuu init\uuuu
,对吗?@Karl:yes,为现实而编辑这是python3处理得更清楚的事情之一:它将拒绝对任何没有
\uuu散列()的对象进行设置。Python2有一个默认的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
,它反映了对象的身份而不是相等。事实上,经典类的行为是相同的(不定义
\uuuuuuuuuuuuuu但后来引入了新样式的类(在Python2.2中),这种行为没有得到正确的复制。对于足够多的版本来说,这一疏忽被忽略了,更改它可能会破坏太多的代码,因此修复它被推迟到Python 3。