UserDict
、dict
、ABC
の違いは何ですか?どちらが推奨されますか?ドキュメントはUserDict
を非推奨にしているようです?
また、UserDictのupdate()
は私のsetitem
メソッドを使用するようですが、dict
は使用しませんか?カスタムのsetitem
関数とgetitem
関数が必要な場合、オーバーライドするのに本当に不可欠なメソッドはどれですか?
ABC
sを使用すると、デフォルトの実装が提供されないため、絶対にすべてのメソッドを実装する必要がありますか?
2つのことを行うdict
を作成したいと思います。
intern()
すべてのキーと値では、UserDict
、dict
、ABC
のどれが私にこれを行うのに最適でしょうか?
実際にデータを保持するカスタムコレクションが必要な場合は、サブクラスdict。これは、インターフェースを拡張したい場合(メソッドの追加など)に特に役立ちます。
ただし、組み込みメソッドはいずれもカスタム___getitem__
_/___setitem__
_を呼び出しません。これらを完全に制御する必要がある場合は、代わりに_collections.MutableMapping
_抽象基本クラスを実装するカスタムクラスを作成してください。
ABCは、実際のデータを格納する手段を提供せず、一部のメソッドのデフォルト実装を備えたインターフェースのみを提供します。ただし、これらのデフォルトの実装では、カスタム___getitem__
_および___setitem__
_が呼び出されます。データを保持するには内部dict
を使用し、すべての抽象メソッドを実装する必要があります:___len__
_、___iter__
_、___getitem__
_、___setitem__
_、および___delitem__
_。
UserDict
モジュールのクラスcollections
(Python 2では、モジュールはUserDict
とも呼ばれます)は、内部のラッパーです) dict
、MutableMapping
ABCの実装。dict
の動作をカスタマイズする場合は、この実装が出発点になる可能性があります。
要約すれば:
dict
のように機能するものを作成します。データを保存するかどうか、またどのように保存するかは完全にあなた次第です。MutableMapping
をストレージとして使用するdict
の実装です。 dictのようなストレージコレクションが必要であるが、dict
によって公開されているいくつかのメソッドをオーバーライドする場合、これはあなたにとって良い出発点かもしれません。ただし、コードを読んで基本的なメソッドがどのように実装されているかを確認し、メソッドをオーバーライドするときに一貫性を保つようにしてください。秘密に基づく Python忍者 本のレシピ
UserDictが通常の辞書操作を超えて持つ唯一の特別なことは、単一の属性です。
data:UserDictクラスの内容を保持するための実際の辞書
辞書の項目にアクセスするには、それらを反復処理するか、items()を呼び出す必要があります。 UserDictインスタンスは同じメソッドをサポートしていますが、items()によって返されるビューは著しく異なります。
>>> from collections import UserDict
>>> a = UserDict(a=1)
>>> d = dict(d=3) # regular dictionary for comparison
>>> for k in d:
... print(k, d[k])
...
d 3
>>> d.items()
dict_items([('d', 3)])
>>> for k in a:
... print(k, a[k])
...
a 1
>>> a.items()
ItemsView({'a': 1})
ディクショナリオブジェクトがキー/値のタプルを返すことに注意してください。 UserDictは、実際の辞書オブジェクトを返します。データ属性を使用して辞書にアクセスする機能と同様に、実行している内容によっては、この違いが重要になる場合があります。
UserDict
クラスは使用しないでください。必要ありません。ドキュメントにあるように、dict
を直接サブクラス化することができます。
ただし、 UserDict
の場合は、DictMixin
モジュールが必要です。
注:DictMixin
は正式に非推奨ではありませんが、Python 3)で削除されました。 collections.MutableMapping
を使用することをドキュメントで推奨しています。ただし、これには欠点があります。辞書インターフェイスをさらに実装する必要があります。__delitem__
、__getitem__
、__iter__
、 __len__
、および__setitem__
。DictMixin
を使用すると、変更したいものだけを実装でき、残りはデフォルトの実装を使用します。
from UserDict import DictMixin
class MyDict(DictMixin, dict):
def __setitem__(self, key, value):
print key, value # just an example
# use intern(key) or whatever here
dict.__setitem__(self, key, value) # or
# super(MyDict, self).__setitem__(key, value)
m = MyDict()
m['a'] = 'b'
# a b
m.update({'a': 'c'})
# a c
自動的にupdate
に__setitem__
を必要に応じて使用させます。