1. ホーム
  2. python

[解決済み] dict の適切なサブクラス化と __getitem__ & __setitem__ のオーバーライドの方法

2023-03-14 11:54:55

質問

あるコードのデバッグをしていて、特定の辞書がいつアクセスされたかを調べたいのです。それは実際には dict をサブクラス化し、いくつかの追加機能を実装したクラスです。とにかく、私がやりたいことは、サブクラスの dict を自分自身でサブクラス化し、オーバーライド __getitem____setitem__ でデバッグ出力を出すことができます。今現在、私は

class DictWatch(dict):
    def __init__(self, *args):
        dict.__init__(self, args)

    def __getitem__(self, key):
        val = dict.__getitem__(self, key)
        log.info("GET %s['%s'] = %s" % str(dict.get(self, 'name_label')), str(key), str(val)))
        return val

    def __setitem__(self, key, val):
        log.info("SET %s['%s'] = %s" % str(dict.get(self, 'name_label')), str(key), str(val)))
        dict.__setitem__(self, key, val)

'name_label' は最終的に設定されるキーで、出力を識別するために使用したいものです。次に、インスツルメンテーションを行うクラスをサブクラス DictWatch の代わりに dict に変更し、スーパーコンストラクタへの呼び出しを変更しました。それでも、何も起こらないようだ。私は賢いと思っていましたが、別の方向に行くべきなのでしょうか。

助けてくれてありがとうございます!

どのように解決するのですか?

あなたがやっていることは絶対にうまくいくはずです。あなたのクラスをテストしてみましたが、ログ ステートメントの開始括弧が欠けていることを除けば、問題なく動作しました。考えられることは 2 つだけです。まず、ログ文の出力は正しく設定されていますか?あなたは logging.basicConfig(level=logging.DEBUG) をスクリプトの先頭に追加する必要があるかもしれません。

2つ目は __getitem____setitem__ の間だけ呼び出されます。 [] のアクセス時にのみ呼び出されます。ですから、必ず DictWatch を経由して d[key] よりも、むしろ d.get()d.set()