set - 集合型の不審な挙動

Pythonでは集合型setをサポートしています。 このsetは中に入っている要素は必ずユニークであることが保証されます。

例えば次のような引数を渡すと重複している要素は省かれます。

>>> set([1,2,3,2,3,4])
set([1, 2, 3, 4])

では同一かどうかを判断する際に __eq__() メソッドを定義したクラスはどうでしょうか?

>>> class A(object):
...     def __init__(self, num):
...             self.num = num
...     def __eq__(self, other):
...             return self.num == other.num
...

このようなクラスのインタンスの比較は __eq__() の戻り値で判断します。

>>> a = A(3)
>>> b = A(3)
>>> c = A(4)
>>> a == b
True
>>> a == c
False

しかしset型は同一かどうかに __eq__() の戻り値を見ていません。 従って上記の ab をsetオブジェクトに入れても 別のものとして処理されてしまうのです。

>>> aa = set([a,a,a])
>>> aa
set([<__main__.A object at 0x10057f190>])
>>> aa.add(b)
>>> aa
set([<__main__.A object at 0x10057f190>, <__main__.A object at 0x10057f210>])

同様にsetオブジェクト同士の比較も同様の動きをします。

>>> aa = set([a])
>>> aa = set([b])
>>> aa = set([b])
>>> aa = set([a])
>>> bb = set([b])
>>> aa == bb
False

しかしリストやタプル等のオブジェクトは __eq__() で同一性を判断します。

>>> (a, b) == (a, a)
True
>>> [a, b] == [a, a]
True

これはバグなのでしょうか?

このページ

inserted by FC2 system