Pythonでsetメソッドをオーバーライドする
-
06-07-2019 - |
質問
オブジェクトをセットに保存するために自動的に別のフォームに変換するカスタムセットを作成したい( Python辞書をネストされていないキーとして使用する)。
add
、 remove
、 __ contains __
、 __ str __
、 update
をオーバーライドした場合、 __ iter __
、他の操作を適切に動作させるのに十分ですか、それとも他のものをオーバーライドする必要がありますか?
解決
collections
の抽象クラスからの作業は、@ kaizer.seが示唆しているように、2.6での適切なソリューションです(なぜsuperを呼び出したいのか、どの機能を委任しようとしているのかわかりません)継承ではなく封じ込めによって最善を尽くすことはできませんか?!)。
update
を取得しないのは確かです-抽象メソッドを提供することにより、 __ le __、__ lt __、__ eq __、__ ne __、__ gt __、__ ge __、__ and __、__ or__ __sub__、 __xor __、isdisjoint
( collections.Set
から)+ clear、pop、remove、__ ior __、__ iand __、__ ixor__、および__isub __
( collectionsから)。 MutableSet
)、これは set
のサブクラス化から得られるものよりはるかに多く(興味のある every メソッドをオーバーライドする必要があります)。必要な他のsetメソッドを提供する必要があります。
collections.Set
のような抽象基本クラスは、 set
や(2.6では)古き良き sets.Set
、非推奨ですが、まだ使用されています(Python 3で削除されました)。 ABCは、継承し(必要に応じて、すべての抽象メソッドを実装すると、一部のメソッドを合成できます)、二次的に「登録」することを意図しています。 ( isinstance
をより使いやすく便利にするために)継承していない場合でも、継承したように見えます。
Python 3.1および2.6の実例です(3.0を使用する正当な理由はありません。3.1には利点があり、欠点はありません):
import collections
class LowercasingSet(collections.MutableSet):
def __init__(self, initvalue=()):
self._theset = set()
for x in initvalue: self.add(x)
def add(self, item):
self._theset.add(item.lower())
def discard(self, item):
self._theset.discard(item.lower())
def __iter__(self):
return iter(self._theset)
def __len__(self):
return len(self._theset)
def __contains__(self, item):
try:
return item.lower() in self._theset
except AttributeError:
return False
他のヒント
Python 2.6の場合:
import collections
print collections.MutableSet.__abstractmethods__
# prints:
# frozenset(['discard', 'add', '__iter__', '__len__', '__contains__'])
サブクラス collections.MutableSet
を実行し、上記のリストのメソッドをオーバーライドします。
上記の最低限の要件が実装されている場合、更新方法自体は非常に簡単です
def update(self, iterable):
for x in iterable:
self.add(x)