web-dev-qa-db-ja.com

タイプの問題なしでPythonリストをサブクラス化する方法は?

Pythonにlistのサブクラスとしてカスタムリストクラスを実装したいと思います。ベースlistからオーバーライドする必要があるメソッドの最小セットは何ですか?すべてのリスト操作の完全な型互換性を取得するためにクラス?

この質問 は少なくとも__getslice__をオーバーライドする必要があることを示唆しています。今後の調査により、__add__および__mul__も必要になります。だから私はこのコードを持っています:

class CustomList(list):
    def __getslice__(self,i,j):
        return CustomList(list.__getslice__(self, i, j))
    def __add__(self,other):
        return CustomList(list.__add__(self,other))
    def __mul__(self,other):
        return CustomList(list.__mul__(self,other))

次のステートメントは、オーバーライドするメソッドがなくても必要に応じて機能します。

l = CustomList((1,2,3))
l.append(4)                       
l[0] = -1
l[0:2] = CustomList((10,11))    # type(l) is CustomList

これらのステートメントは、上記のクラス定義のオーバーライドメソッドでのみ機能します。

l3 = l + CustomList((4,5,6))    # type(l3) is CustomList
l4 = 3*l                        # type(l4) is CustomList
l5 = l[0:2]                     # type(l5) is CustomList

私が達成する方法がわからない唯一のことは、拡張スライスが正しいタイプを返すようにすることです:

l6 = l[0:2:2]                   # type(l6) is list

CustomListl6のタイプとして取得するには、クラス定義に何を追加する必要がありますか?

また、拡張スライシング以外に、結果がlistではなくCustomListタイプになるリスト操作はありますか?

33
silvado

最初に、私はあなたが従うことをお勧めします ビョルン・ポレックスのアドバイス (+1)。

この特定の問題(type(l2 + l3) == CustomList)を回避するには、カスタム __add__() を実装する必要があります。

   def __add__(self, rhs):
        return CustomList(list.__add__(self, rhs))

そして 拡張スライス の場合:

    def __getitem__(self, item):
        result = list.__getitem__(self, item)
        try:
            return CustomList(result)
        except TypeError:
            return result

私もお勧めします...

pydoc list

...コマンドプロンプトで。どのメソッド list が公開されているかがわかります。これにより、オーバーライドする必要のあるメソッドについて適切な指標が得られます。

23
Johnsyweb

おそらく、ドキュメントの次の2つのセクションを読む必要があります。

編集:拡張スライシングを処理するには、__getitem__- methodはスライスオブジェクトを処理します( here を参照してください。少し下にあります)。

20
Björn Pollex