Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/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 即使在覆盖_uhash___()和_eq__()之后,自定义对象也不能作为字典键正常工作_Python_Python 3.x_Oop - Fatal编程技术网

Python 即使在覆盖_uhash___()和_eq__()之后,自定义对象也不能作为字典键正常工作

Python 即使在覆盖_uhash___()和_eq__()之后,自定义对象也不能作为字典键正常工作,python,python-3.x,oop,Python,Python 3.x,Oop,注意:我意识到了这个完全相同的问题。但是,我已经尝试了那里的答案所提出的解决方案,它们对我不起作用(参见下面的示例代码) B对象具有A的列表A由只有两个整数和一个整数的元组组成 我试图使用B对象作为字典中的键。但是,即使在实现了我自己的\uuuuuueq\uuuuu()和\uuuuuuu hash\uuuuuu()方法之后,我的字典的长度甚至在添加了相同的对象之后也会增加 见下面的代码: class A: def __init__(self, my_tuple, my_integer)

注意:我意识到了这个完全相同的问题。但是,我已经尝试了那里的答案所提出的解决方案,它们对我不起作用(参见下面的示例代码)


B
对象具有
A
的列表
A
由只有两个整数和一个整数的元组组成

我试图使用
B
对象作为字典中的键。但是,即使在实现了我自己的
\uuuuuueq\uuuuu()
\uuuuuuu hash\uuuuuu()
方法之后,我的字典的长度甚至在添加了相同的对象之后也会增加

见下面的代码:

class A:
    def __init__(self, my_tuple, my_integer):
        self.my_tuple = my_tuple
        self.my_integer = my_integer
    def __eq__(self, other):
        return self.my_tuple == other.my_tuple and self.my_integer == other.my_integer

class B:
    def __init__(self):
        self.list_of_A = []
    def add(self, my_tuple, my_integer):
        new_A = A(my_tuple, my_integer)
        self.list_of_A.append(new_A)
    def __hash__(self):
        return hash(repr(self))
    def __eq__(self, other):
        for i in range(len(self.list_of_A)):
            if self.list_of_A[i] != other.list_of_A[i]:
                return False
        return True

b_1 = B()
b_1.add((1,2), 3)

b_2 = B()
b_2.add((1,2), 3)

my_dict = {}

my_dict[b_1] = 'value'
print(len(my_dict))

my_dict[b_2] = 'value_2'
print(len(my_dict))
我得到的结果是

1
2

预期产量为

1
1


因为我正在添加相同的对象(即:相同的属性值)。

哈希不相等,因为
repr()
s不相等。考虑下面的示例,我刚才在Python控制台上使用代码:
>>> x = B()
>>> y = B()
>>> repr(x)
'<__main__.B object at 0x7f7b3a20c358>'
>>> repr(y)
'<__main__.B object at 0x7f7b3aa197b8>'

散列(repr(self))
在这种情况下不是合适的散列。两个相等的对象在此实现中将不具有相同的哈希。你需要一个基于你认为相等的值一致的散列。<代码> BY1和 BY2被认为是不同的密钥,因为它们的散列值会有所不同。通常,一个对象的默认repr包含其内存地址,这两个对象的内存地址不同,它们的哈希也不同。您实现了
hash
,但它使用了未实现的
repr
。。。因此,这将返回一个默认值
,其中最后一个数字是内存中的地址。
class A:
    ...
    def __repr__(self):
        return f"A(my_tuple:{self.my_tuple}, my_integer:{self.my_integer})"

class B:
    ...
    def __repr__(self):
        return f"B(list_of_a:{self.list_of_a})"