我在两个类的对象之间有递归关系:Foo
有一个对象(在其属性中),每个都有一个对象(在其属性中)。我已经实现如下 MWE 所示,但测试失败。为什么?set
Bar
bars
Bar
list
Foo
foos
根据Python Glossary, aset
只能包含hashable
对象和hashable
对象:
一个对象是
hashable
如果它有一个在其生命周期内永远不会改变的哈希值(它需要一个__hash__()
方法),并且可以与其他对象进行比较(它需要一个__eq__()
方法)。
我真的不知道我下面的 MWE 是否满足对象具有永远不会更改的哈希,因为哈希取决于列表中的其他对象并设置属性。有没有办法解决这个问题?
最小的工作示例:
import unittest
class Test(unittest.TestCase):
def test_foo_bar(self):
foo = Foo()
bar = Bar()
bar.add_foo(foo)
print(bar)
print(foo.bars)
print(hash(bar))
for bar in foo.bars:
print(hash(bar))
# The previous print lines print the following:
# <mwe2.Bar object at 0x105ba8080>
# {<mwe2.Bar object at 0x105ba8080>}
# -9223096319794529578
# -9223096319794529578
# The following assertion is OK
self.assertTrue(bar in {bar})
# The following assertion fails with AssertionError: False is not true
self.assertTrue(bar in foo.bars)
class Foo:
def __init__(self):
self.bars = set()
def __hash__(self) -> int:
return hash(self.__dict__.values())
class Bar:
def __init__(self):
self.foos = list()
def __hash__(self) -> int:
return hash(tuple(self.foos))
def add_foo(self, foo: "Foo"):
foo.bars.add(self)
self.foos.append(foo)
if __name__ == '__main__':
unittest.main()
我使用 CPython,Python 3.6.x。