10

list挿入時に、「Aは常にBの前に来る必要があります」または「Cが含まれている場合は常に最後に来る必要があります」という形式の特定の制約を自動的にチェックするPythonオブジェクトが必要です。

これを実装するための最も簡単/最速の方法は何ですか。明らかなアプローチは、その内容( append、、、など)を変更するリストデータ型のすべてのメソッドをオーバーライドし、操作後も制約が保持されていることを確認することです。これらの方法がたくさんあるので、これはかなり退屈なことです。もっと簡単な方法はありますか?extendinsert

4

3 に答える 3

5

collections.MutableSequence抽象基本クラスからサブクラス化することを強くお勧めします。list欠点は、 (user4815162342が指摘しているように)のサブクラスとして認識されないことです。ただし、結果のクラスを使用する人々が正しいことをしている限り、それはほとんど問題になりません(つまり、ダックタイピングを使用するか、具象クラスではなく抽象基本クラスをに渡します isinstance)。

これの素晴らしい点は、次のメソッドを定義すると、残りのMutableSequenceインターフェイスを無料で入手できることです。MutableSequenceこれは、さらにカスタマイズするためのテンプレートとして使用できる具体的なサブクラスです。あなたの場合、あなたは、、、、__init__そしてをカスタマイズするだけでよいはずです。他のすべてはそれらの観点から定義されているため、挿入したチェックはすべて実行されます。__setitem__insert__delitem__

import collections
class MyList(collections.MutableSequence):
    def __init__(self, it=()):
        self._inner = list(it)
    def __len__(self):
        return len(self._inner)
    def __iter__(self):
        return iter(self._inner)
    def __contains__(self, item):
        return item in self._inner
    def __getitem__(self, index):
        return self._inner[index]
    def __setitem__(self, index, value):
        self._inner[index] = value
    def __delitem__(self, index):
        del self._inner[index]
    def __repr__(self):
        return 'MyList({})'.format(self._inner)
    def insert(self, index, item):
        return self._inner.insert(index, item)

いくつかの簡単なテスト:

>>> ml = MyList('foo')
>>> ml
MyList(['f', 'o', 'o'])
>>> ml.append(5)
>>> ml
MyList(['f', 'o', 'o', 5])
>>> ml.reverse()
>>> ml
MyList([5, 'o', 'o', 'f'])
于 2012-11-18T19:23:47.510 に答える
1

タイプがのサブタイプでなければならない場合、listオプションは制限されます。リストをサブクラス化し、ミューテイタメソッドをオーバーライドする必要があります。たとえば、などの特別なメソッドを忘れないで__setitem__ください。悪いニュースは、これらの方法が使用されることを強制する方法がないということです。誰でも、いつでも:を呼び出しlist.append(your_list, new_elem)て、をバイパスできますappend。さらに悪いことに、Pythonの実装はまさにそれを場所で行います。(これは、dictとタプルの場合によく見られます。)

タイプがから継承する必要がない場合は、とをlist見てください。UserListcollections.MutableSequence

于 2012-11-18T18:59:01.520 に答える
0

サブクラス化せず、プロキシします。すべての呼び出しをプロキシリストに渡すようにlistオーバーライドしてから、制約を確認します。__getattribute__

于 2012-11-18T19:00:31.960 に答える