我想将集合的元素限制为某个类的实例。我应该设置子类并覆盖 add 方法吗?我该怎么做?
问问题
35 次
1 回答
2
首先,在构建一组自定义对象时,您可能需要查看这个问题及其答案。简而言之,您需要定义诸如__hash__()
和之类的方法,__eq__()
以便您可以将它们添加到集合中:
class Foo:
def __init__(self, value=0):
self.value = value
def __hash__(self):
return self.value
def __eq__(self, other):
return isinstance(other, Foo) and self.value == other.value
现在您可以比较对象和set
罐子:
In [19]: a = Foo()
In [20]: b = Foo()
In [21]: c = Foo(1)
In [22]: a == b
Out[22]: True
In [23]: b == c
Out[23]: False
In [24]: s = set([a, b, c])
In [25]: s
Out[25]:
set([<__main__.Foo instance at 0x267f758>,
<__main__.Foo instance at 0x267f950>])
In [26]: s.add(Foo())
In [27]: s
Out[27]:
set([<__main__.Foo instance at 0x267f758>,
<__main__.Foo instance at 0x267f950>])
问题是,你仍然可以添加一些完全不同的东西:
In [28]: s.add(1)
In [29]: s
Out[29]:
set([<__main__.Foo instance at 0x267f758>,
<__main__.Foo instance at 0x267f950>,
1])
一种方法是按照您的建议覆盖add()
方法:set
In [30]: class FooSet(set):
....: def add(self, elem):
....: if isinstance(elem, Foo):
....: set.add(self, elem)
....: else:
....: raise TypeError('%s is not a Foo' % elem)
....: # or just put "pass" here for silent behavior
In [31]: s = FooSet([a, b, c])
In [32]: s
Out[32]:
set([<__main__.Foo instance at 0x267f758>,
<__main__.Foo instance at 0x267f950>])
In [33]: s.add(Foo())
In [34]: s
Out[34]:
set([<__main__.Foo instance at 0x267f758>,
<__main__.Foo instance at 0x267f950>])
In [35]: s.add(Foo(2))
In [36]: s
Out[36]:
set([<__main__.Foo instance at 0x267f758>,
<__main__.Foo instance at 0x267f950>,
<__main__.Foo instance at 0x26808c0>])
In [37]: s.add(2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
...
TypeError: 2 is not a Foo
于 2012-04-25T12:19:39.947 回答