一组可变对象被搞糊涂了 [英] Set of mutable objects gets befuddled

查看:54
本文介绍了一组可变对象被搞糊涂了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个仅根据其属性内容进行比较的类,因此具有相同值的两个对象等价的.

I have a class that is compared only based on the content of its attributes, so that two objects with the same values are equivalent.

class a(object):
    def __init__(self, value):
        self.value = value
    def __repr__(self):
        return 'a(value={})'.format(self.value)
    def __hash__(self):
        return hash(self.__repr__())
    def __eq__(self, other):
        if not isinstance(other, self.__class__):
            return NotImplemented
        return self.value == other.value
    def __ne__(self, other):
        return not self.__eq__(other)

当我创建类的对象并将其添加到集合时,它被正确添加.然后我用不同的值创建第二个对象并修改第一个对象以匹配第二个对象.该集合现在显示修改后的对象,a1a2 之间的比较正确显示为 true.

When I create an object of the class and add it to a set it is added correctly. Then I create a second object with a different value and modify the first one to match the second object. The set now shows the modified object and the comparison between a1 and a2 correctly says true.

如果我现在尝试在集合中搜索 a1a2,该集合无法找到它们,即使 a1被明确添加并且 a2 比较为真.

If I now try to search in the set for a1 or a2, the set does not manage to find them, even if a1 was explicitly added and a2 compares true.

# create the object and a set with it
a1 = a(1)
a_set = set([a1])
print('Elements in set are: {}'.format(','.join([element.__repr__() for element in a_set])))

# build a new object and modify the original object to be identical to the second
a2 = a(2)
a1.value = 2
print('Elements in set are: {}'.format(','.join([element.__repr__() for element in a_set])))

# object compare fine
print('{} == {} is {}'.format(a1, a2, a1 == a2))

# none of the object are in the set (even if a1 was added to the set)
print('{} in set is {}'.format(a1, a1 in a_set))
print('{} in set is {}'.format(a2, a2 in a_set))
print('Elements in set are: {}'.format(','.join([element.__repr__() for element in a_set])))

我知道这可能是由于 a1 存储在与具有原始值而不是修改值相对应的哈希下的集合中,但无论如何问题是添加 a2 到集合会给我第二个元素,相当于第一个.有没有办法解决这个问题?

I understand that this could be due to a1 being stored in the set under the hash corresponding to having the original value, not the modified value, but the problem in any case is that adding a2 to the set would give me a second element which is equivalent to the first. Is there a way out of this?

推荐答案

对象的哈希值在第一次存储在集合的哈希表中时被存储.即使对象发生变异,它也不会更新.

The hash value of the object is stored the first time the object is stored in the set's hash table. It does not get updated even when the object is mutated.

初始哈希值hash("a(value=1)") 是正在使用的,而不是hash("a(value=2)").

The initial hash value hash("a(value=1)") is what is in use not hash("a(value=2)").

这就是为什么 set 永远不会使用可变项的原因之一;除非你使用了后门.

This is one of the reasons why mutable items are never taken by sets in the first place; except you used a backdoor.

修改 a1.value = 1 会将您的对象恢复为与集合包含的内容相同的匹配项.

Modifying a1.value = 1 restores your object as the same match as what the set contains.

这篇关于一组可变对象被搞糊涂了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆