通常,如果我们需要将一个对象插入到一个集合中,我们应该使它可以散列(通过实现散列函数)和可比较的(并实现一个比较函数)。 Set不提供访问其元素的机制,因此不能直接变异,但很容易被规避。 改变设定项目的一般模式如下
i = next(iter(x))
update(i)
x.add(i)
这通常似乎适用于几乎所有情况,除非是在创建意外漏洞时。
class Foo(object):
def __init__(self, x):
self.x = x
self.count = 0
def __hash__(self):
return hash((self.x, ))
def __iadd__(self, n):
self.count += n
def __eq__(self, other):
return self.x == other.x
>>> x = {Foo(1)}
>>> i = next(iter(x))
>>> i+=1
>>> x.add(i)
>>> x
set([None, <__main__.Foo object at 0x0279D8B0>])
我的猜测是改变一个set元素,而更新可能会导致意外行为,但是调用next只会获取不应该成为问题的值(我猜的副本)。
知道问题可能是什么?
答案 0 :(得分:3)
[
__iadd__
]应该尝试就地进行操作(修改自我)和 返回结果(可能是,但不一定是自己)
因此,
def __iadd__(self, n):
self.count += n
return self
然后,
class Foo(object):
def __init__(self, x):
self.x = x
self.count = 0
def __hash__(self):
return hash((self.x, ))
def __iadd__(self, n):
self.count += n
return self
def __eq__(self, other):
return self.x == other.x
x = {Foo(1)}
i = next(iter(x))
i+=1
x.add(i)
print(x)
产量
set([<__main__.Foo object at 0x7f19ae8b9f10>])
答案 1 :(得分:1)
您可能希望以 iadd 方式返回自我。