Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何为我的类实现uuu cmp_uuu()和uuu hash_uuu()?_Python_Dictionary_Hash_Collections_Python 2.x - Fatal编程技术网

Python 如何为我的类实现uuu cmp_uuu()和uuu hash_uuu()?

Python 如何为我的类实现uuu cmp_uuu()和uuu hash_uuu()?,python,dictionary,hash,collections,python-2.x,Python,Dictionary,Hash,Collections,Python 2.x,我想编写一个类,它可以用作散列集合中的键(例如,在dict中)。我知道默认情况下用户类是可散列的,但是在这里使用id(self)是错误的 我的类持有一个元组作为成员变量。从元组派生似乎不是一个选项,因为在我的构造函数中,我没有得到与元组构造函数相同的参数。但也许这不是一个限制 我需要的基本上是一个元组的散列,就像一个真正的元组所给出的那样 hash(self.member\u tuple)就是这样做的 这里的想法是两个元组可以相等,而它们的id不相等 如果我实现我的\uuuu cmp\uuuu(

我想编写一个类,它可以用作散列集合中的键(例如,在
dict
中)。我知道默认情况下用户类是可散列的,但是在这里使用
id(self)
是错误的

我的类持有一个
元组作为成员变量。从
元组
派生似乎不是一个选项,因为在我的构造函数中,我没有得到与
元组
构造函数相同的参数。但也许这不是一个限制

我需要的基本上是一个
元组的散列,就像一个真正的元组所给出的那样

hash(self.member\u tuple)
就是这样做的

这里的想法是两个元组可以相等,而它们的
id
不相等

如果我实现我的
\uuuu cmp\uuuu()
,如下所示:

def __cmp__(self, other):
    return cmp(self, other)
def __cmp__(self, other):
    return cmp(self.member_tuple, other)
这会自动求助于
散列(self)
进行比较吗。。。或者我应该按以下方式实施:

def __cmp__(self, other):
    return cmp(self, other)
def __cmp__(self, other):
    return cmp(self.member_tuple, other)
My
\uuuu hash\uuuu()
函数用于返回保留的
元组的哈希值,即:

def __hash__(self):
    return hash(self.member_tuple)
基本上,
\uu cmp\uu()
\uu hash\uu()
是如何相互作用的?我不知道在
\uuu cmp\uuu()
中,
其他
是否已经是散列,我是否应该与“我的”散列(即保留的
元组
中的一个)或
自身
进行比较

那么哪一个是正确的呢


有谁能解释一下这一点,并可能向我指出文档吗?

我不会使用
\uuuuCMp\uuuuuuu
,而是坚持使用
\uuueq\uuuuu
。对于散列,这就足够了,您不想在这里扩展到可排序。此外,为了支持丰富的比较方法,
\uuuuuuueq\uuuu
\uult\uuuuu
\ugt\uuuuu
等,
\uuuuuuu>从Python 3中删除了

接下来,当成员元组相等时,您的
\uuuuu eq\uuuu
应返回True:

def __eq__(self, other):
    if not isinstance(other, ThisClass):
        return NotImplemented
    return self.member_tuple == other.member_tuple
other
对象的类型不同时,返回
NotImplemented
单例是一种很好的做法,因为这将把相等性测试委托给
other
对象;如果它没有实现
\uuu eq\uuu
或者还返回
未实现
,Python将返回标准的
id()
测试

您的
\uuuuuuuuuuuuuuuuuuuuuuuuuu散列
实现非常正确

因为散列并不意味着是唯一的(它只是在散列表中选择一个槽的一种方法),所以使用相等来确定匹配的键是否已经存在或者是否发生了散列冲突。因此,如果对象散列到的插槽为空,则不会调用
\uuuuuuueq\uuuuuuu
(如果
\uuuuuuuuueq\uuuuu
则不会调用
\uuuucmp\uuuuuuuuuu

这确实意味着,如果两个对象被视为相等(
a.uuu eq\uuuu(b)
返回
True
),那么它们的哈希值也必须相等。否则,最终可能会导致字典损坏,因为Python将无法再确定哈希表中是否已经存在键

如果
\uuuu eq\uuuu
\uuuu hash\uuuu
方法都将其职责委托给
self.member\u tuple
属性,则您将维护该属性;您可以相信基本
元组
类型正确地实现了这一点

请参阅和。如果您感到好奇,我已经写过
dict
set
类型如何在内部工作:


谢谢。不过,最后一段让我感到困惑。如何保证哈希值相同?我可以假设在对
元组进行哈希运算时
?我不可能知道任何其他给定的
元组的哈希值是否与成员元组的哈希值相同,可以吗?@0xC000002L:您将哈希函数委托给元组的方式与委托相等性测试的方式相同,因此您可以很好地维护该属性。如果元组开始产生不同的散列值,即使对于相等的元组也是如此,那么这将是一个更大的问题,您可以放心,它会很快得到修复。