セットの要素を特定のクラスのインスタンスに制限したいと思います。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])
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 に答える