[解決済み】dictを「完璧に」オーバーライドするには?
質問
のサブクラスを作るにはどうしたらいいですか? ディクショナリー ということです。最終的なゴールは、シンプルな ディクショナリー で、キーは小文字である。
これを動作させるためにオーバーライドできるプリミティブの小さなセットがあるはずだと思うのですが、私のすべての調査と試みによると、そうではなさそうなのです。
-
もし私が オーバーライド
__getitem__
/__setitem__
であればget
/set
が動作しない。 どうすれば動くようになるのでしょうか? 確かに、私はそれらを個別に実装する必要はないのでしょうか? -
ピックリングが機能しないように、私は実装する必要があるのでしょうか?
__setstate__
などがありますか? -
を使用すればよいのでしょうか? mutablemappingを使用する (を使うべきではないようです)。
UserDict
またはDictMixin
)? もしそうなら、どのように?ドキュメントを読んでもよくわからないのですが。
以下は、私の初体験です。
get()
は動作しませんし、他にも細かい問題がたくさんあるのは間違いありません。
class arbitrary_dict(dict):
"""A dictionary that applies an arbitrary key-altering function
before accessing the keys."""
def __keytransform__(self, key):
return key
# Overridden methods. List from
# https://stackoverflow.com/questions/2390827/how-to-properly-subclass-dict
def __init__(self, *args, **kwargs):
self.update(*args, **kwargs)
# Note: I'm using dict directly, since super(dict, self) doesn't work.
# I'm not sure why, perhaps dict is not a new-style class.
def __getitem__(self, key):
return dict.__getitem__(self, self.__keytransform__(key))
def __setitem__(self, key, value):
return dict.__setitem__(self, self.__keytransform__(key), value)
def __delitem__(self, key):
return dict.__delitem__(self, self.__keytransform__(key))
def __contains__(self, key):
return dict.__contains__(self, self.__keytransform__(key))
class lcdict(arbitrary_dict):
def __keytransform__(self, key):
return str(key).lower()
解決方法は?
のような振る舞いをするオブジェクトを書けばいいのです。
dict
を使うと非常に簡単です。
ABC
の抽象基底クラス(Abstract Base Classes)です。
collections.abc
モジュールです。 メソッドを見逃した場合にも教えてくれるので、以下はABCをシャットアウトする最小限のバージョンです。
from collections.abc import MutableMapping
class TransformedDict(MutableMapping):
"""A dictionary that applies an arbitrary key-altering
function before accessing the keys"""
def __init__(self, *args, **kwargs):
self.store = dict()
self.update(dict(*args, **kwargs)) # use the free update to set keys
def __getitem__(self, key):
return self.store[self._keytransform(key)]
def __setitem__(self, key, value):
self.store[self._keytransform(key)] = value
def __delitem__(self, key):
del self.store[self._keytransform(key)]
def __iter__(self):
return iter(self.store)
def __len__(self):
return len(self.store)
def _keytransform(self, key):
return key
ABCの無料メソッドをいくつか取得します。
class MyTransformedDict(TransformedDict):
def _keytransform(self, key):
return key.lower()
s = MyTransformedDict([('Test', 'test')])
assert s.get('TEST') is s['test'] # free get
assert 'TeSt' in s # free __contains__
# free setdefault, __eq__, and so on
import pickle
# works too since we just use a normal dict
assert pickle.loads(pickle.dumps(s)) == s
をサブクラス化することはないでしょう。
dict
(または他の組み込み関数)を直接使用します。それはしばしば意味をなしません。なぜなら、実際にやりたいことは
のインターフェイスを実装します。
dict
. そして、それこそがABCの目的なのです。
関連
-
[解決済み] 'DataFrame' オブジェクトに 'sort' 属性がない
-
[解決済み] プログラムの実行やシステムコマンドの呼び出しはどのように行うのですか?
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] 辞書を値で並べ替えるにはどうしたらいいですか?
-
[解決済み] Pythonで辞書に新しいキーを追加するにはどうすればよいですか?
-
[解決済み] Pythonの辞書からキーを削除するにはどうしたらいいですか?
-
[解決済み] 辞書のリストを辞書の値でソートするにはどうしたらいいですか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Pythonの非常に便利な2つのデコレーターを解説
-
opencvとpillowを用いた顔認証システム(デモあり)
-
python string splicing.join()とsplitting.split()の説明
-
[解決済み】TypeError: unhashable type: 'numpy.ndarray'.
-
[解決済み] [Solved] sklearn error ValueError: 入力に NaN、infinity または dtype('float64') に対して大きすぎる値が含まれている。
-
[解決済み】インポートエラー。モジュール名 urllib2 がない
-
[解決済み】 AttributeError("'str' object has no attribute 'read'")
-
[解決済み】LogisticRegression: Pythonでsklearnを使用して、未知のラベルタイプ: '連続'を使用しています。
-
[解決済み】ValueError: pickleプロトコルがサポートされていません。3、python2 pickleはpython3 pickleでダンプしたファイルを読み込むことができない?
-
[解決済み】 TypeError: += でサポートされていないオペランド型: 'int' および 'list' です。