あなただけのリストの挙動の一部、使用組成物(すなわち、あなたのインスタンスが実際のリストへの参照を保持)とするために必要な唯一のメソッドを実装したい場合あなたが望む行動。これらのメソッドは、あなたのクラスの任意のインスタンスは、例えば、への参照を保持している実際のリストに作業を委任する必要がありますだけでは__getitem__
を実装
def __getitem__(self, item):
return self.li[item] # delegate to li.__getitem__
は、例えば、反復やスライシングのために、あなたの機能の驚くべき量を与えるだろう。あなたがリストのフル行動をしたい場合は
>>> class WrappedList:
... def __init__(self, lst):
... self._lst = lst
... def __getitem__(self, item):
... return self._lst[item]
...
>>> w = WrappedList([1, 2, 3])
>>> for x in w:
... x
...
1
2
3
>>> w[1:]
[2, 3]
は、collections.UserList
から継承します。 UserList
は、リストのデータ型の完全なPython実装です。
なぜlist
から直接継承しないのですか?
list
(またはC言語で書かれた他の組み込み関数)から直接継承する大きな問題の1つは、組み込み関数のコードが、ユーザーによって定義されたクラスでオーバーライドされた特別なメソッドを呼び出すかどうかということです。ここでpypy docsから関連の抜粋です:
を公式には、CPythonのは、まさに組み込み型暗黙的に呼び出さないか、取得のサブクラスのメソッドをオーバーライドしたときのために、まったくのルールを持っていません。近似として、これらのメソッドは、同じオブジェクトの他の組み込みメソッドによって呼び出されることはありません。例えば、dictのサブクラス内のオーバーライドされた__getitem__
は、例えば、組み込みのget
メソッド。
ルチアーノRamalhoのFluent Pythonから別の引用、ページ351:
サブクラスは、辞書やリストなどの種類に内蔵または組み込みメソッドはほとんどUSER-無視しているため、直接がち エラー - であるSTR定義された オーバーライド。組み込み関数をサブクラス化する代わりに、簡単に拡張できるように設計されたコレクション モジュールのUserDict、UserListおよびUserStringからクラス を派生させます。
...ともっと、ページ370+:
ふらちな組み込み関数:バグや機能? 組み込みのdict、list、およびstrの型は、Python自体の不可欠なビルディングブロックです。したがって、 は高速でなければなりません。そのため、CPythonは、組み込みの メソッドがサブクラスによってオーバーライドされたメソッドと協調しないことによって誤動作を引き起こすショートカットを採用しました。
ビットの周りにプレーした後、list
組み込みの問題はそれほど重要であると思われる(私はしばらくの間はPython 3.4でそれを破るしようとしましたが、本当に明白な予期しない動作を見つけられませんでした)が、私はまだ望んでいました原則的に何が起こるかのデモンストレーションを投稿するには、ので、ここでdict
と1とUserDict
です:
>>> class MyDict(dict):
... def __setitem__(self, key, value):
... super().__setitem__(key, [value])
...
>>> d = MyDict(a=1)
>>> d
{'a': 1}
>>> class MyUserDict(UserDict):
... def __setitem__(self, key, value):
... super().__setitem__(key, [value])
...
>>> m = MyUserDict(a=1)
>>> m
{'a': [1]}
あなたが見ることができるように、dict
から__init__
方法は、当社からの__init__
方法ながら、上書き__setitem__
方法を無視UserDict
はそうしなかった。
あなたは、2つのオプションを持っています'。時代のほとんどは2)1つは行く方法になります。 –
@imaluengoまたは3)[抽象基本クラス](https://docs.python.org/3/library/collections.abc.html#collections-abstract-base-classes)を使用してください – jonrsharpe
4件のクローズリクエストがあります。何故ですか?時々私はスタックオーバーフローを理解していません...:-S – Michael