6

I'm implementing a caching service in python. I'm using a simple dictionary so far. What I'd like to do is to count number of hits (number of times when a stored value was retrieved by the key). Python builtin dict has no such possibility (as far as I know). I searched through 'python dictionary count' and found Counter (also on stackoverflow), but this doesn't satisfy my requirements I guess. I don't need to count what already exists. I need to increment something that come from the outside. And I think that storing another dictionary with hits counting only is not the best data structure I can get :)

Do you have any ideas how to do it efficiently?

4

5 に答える 5

4

dict組み込みクラスをサブクラス化できます。

class CustomDict(dict):
    def __init__(self, *args, **kwargs):
        self.hits = {}
        super(CustomDict, self).__init__(*args, **kwargs)

    def __getitem__(self, key):
        if key not in self.hits:
            self.hits[key] = 0
        self.hits[key] += 1
        return super(CustomDict, self).__getitem__(key)

利用方法:

>>> d = CustomDict()
>>> d["test"] = "test"
>>> d["test"]
'test'
>>> d["test"]
'test'
>>> d.hits["test"]
2
于 2013-10-18T07:27:05.940 に答える
0

組み込みの dict データ型をオーバーロードする方がはるかに簡単です。これで問題は解決します。

def CountDict(dict):
    count = {}

    def __getitem__(self, key):
        CountDict.count[key] = CountDict.count.get(key, 0) + 1
        return super(CountDict, self).__getitem__(self, key)

    def __setitem__(self, key, value):
        return super(CountDict, self).__setitem__(self, key, value)

    def get_count(self, key):
        return CountDict.count.get(key, 0)

これにより、柔軟性が大幅に向上します。複雑さをあまり必要としない場合は、読み取り数と書き込み数の 2 つのカウントを使用できます。スーパーの詳細については、こちらを参照してください。

キーを読み取るためのカウントを保持するという OP のニーズを満たすために編集されました。出力は get_count メソッドを呼び出すことで取得できます。

>>>my_dict = CountDict()
>>>my_dict["a"] = 1
>>>my_dict["a"]
>>>1
>>>my_dict["a"]
>>>1
>>>my_dict.get_count("a")
>>>2
于 2013-10-18T07:51:55.383 に答える
-1

免責事項:私はの著者ですkids.cache

デフォルトでキャッシュ ストアとして使用する単純なライブラリであるkids.cacheをチェックすると、ヒットミスdictを含むキャッシュ統計が返されます。

>>> from kids.cache import cache

>>> @cache
... def meth(a, b):
...     print("Taking some time", a, b)
...     return a + b

1回のミスと1回のヒット:

>>> meth(1, 2)        ## Miss !
Taking some time 1 2
3
>>> meth(1, 2)        ## Hit !
3

ミスを追加しましょう:

>>> meth(1, 3)        ## Miss !
Taking some time 1 2
4

それでは、キャッシュ情報を尋ねてみましょう。

>>> meth.cache_info()
CacheInfo(type='dict', hits=1, misses=2, maxsize=None, currsize=2)

さらに進むには

kids.cache のソース コードをチェックして、キャッシング情報がどのように実装されているかを確認できます。キャッシュストア内に統計を保存しないことに注意してください。値を保持するのはキャッシュ関数です。

dictこれは、それぞれにキャッシュ統計関数を実装する必要なく、さまざまなキャッシュ ストア (および古き良きものと同じくらい単純なもの) を使用できるため、最もクリーンな方法だと思います。この最後のアイデアは、優れたcachetoolsを書いた Thomas Kemmer によるものです。

おそらく、広範な docskids.cacheを備えたすぐに使用できるものもあります。依存関係がなく、ファイルが 1 つだけで、python2 と python3 で動作し、使いやすく、必要に応じて複雑なキャッシュも可能です。

于 2015-02-02T03:09:59.450 に答える