1
我想限制集合的元素是某個類的實例。我應該繼承set並重寫add方法嗎?我將如何做到這一點?實現一個檢查python 2.7的add方法中的類型的正確方法是什麼?
我想限制集合的元素是某個類的實例。我應該繼承set並重寫add方法嗎?我將如何做到這一點?實現一個檢查python 2.7的add方法中的類型的正確方法是什麼?
首先,在構建一組自定義對象時,您可能需要查看this question及其答案。簡單地說,你需要定義方法,如__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])
一種方式是覆蓋按照您的建議使用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