web-dev-qa-db-ja.com

Pythonキャッシュライブラリはありますか?

Pythonキャッシングライブラリを探していますが、これまでのところ何も見つかりません。キーとその有効期限を設定して取得できるシンプルなdictのようなインターフェイスが必要です。バックキャッシュされます。

cache.get(myfunction, duration=300)

存在する場合はキャッシュからアイテムを取得します。存在しない場合や期限切れの場合は関数を呼び出して保存します。誰かがこのようなことを知っていますか?

107
46
Corbin March

Python 3.2ではfunctoolsライブラリのデコレータ @ lru_cache を使用できます。これは最後に使用されたキャッシュなので、その中のアイテムに有効期限はありません。しかし、高速ハックとして非常に便利です。

from functools import lru_cache

@lru_cache(maxsize=256)
def f(x):
  return x*x

for x in range(20):
  print f(x)
for x in range(20):
  print f(x)
58
Genma

Memoize decorator もご覧ください。おそらく、あまり変更を加えなくても、必要な処理を実行できます。

27
tgray

Joblibhttp://packages.python.org/joblib/ は、Memoizeパターンでのキャッシュ機能をサポートしています。ほとんどの場合、アイデアは計算コストの高い関数をキャッシュすることです。

>>> from joblib import Memory
>>> mem = Memory(cachedir='/tmp/joblib')
>>> import numpy as np
>>> square = mem.cache(np.square)
>>> 
>>> a = np.vander(np.arange(3)).astype(np.float)
>>> b = square(a)                                   
________________________________________________________________________________
[Memory] Calling square...
square(array([[ 0.,  0.,  1.],
       [ 1.,  1.,  1.],
       [ 4.,  2.,  1.]]))
___________________________________________________________square - 0...s, 0.0min

>>> c = square(a)

関数で@ memory.cacheデコレータを使用するなどの凝ったこともできます。ドキュメントはこちらです: http://packages.python.org/joblib/memory.html

14
j13r

誰もまだ棚について言及していません。 https://docs.python.org/2/library/shelve.html

Memcachedではありませんが、よりシンプルに見え、ニーズに合うかもしれません。

12
NuclearPeon

python memcached API は一般的なツールですが、自分で使用したことはなく、必要な機能をサポートしているかどうかはわかりません。

9
David Berger
import time

class CachedItem(object):
    def __init__(self, key, value, duration=60):
        self.key = key
        self.value = value
        self.duration = duration
        self.timeStamp = time.time()

    def __repr__(self):
        return '<CachedItem {%s:%s} expires at: %s>' % (self.key, self.value, time.time() + self.duration)

class CachedDict(dict):

    def get(self, key, fn, duration):
        if key not in self \
            or self[key].timeStamp + self[key].duration < time.time():
                print 'adding new value'
                o = fn(key)
                self[key] = CachedItem(key, o, duration)
        else:
            print 'loading from cache'

        return self[key].value



if __== '__main__':

    fn = lambda key: 'value of %s  is None' % key

    ci = CachedItem('a', 12)
    print ci 
    cd = CachedDict()
    print cd.get('a', fn, 5)
    time.sleep(2)
    print cd.get('a', fn, 6)
    print cd.get('b', fn, 6)
    time.sleep(2)
    print cd.get('a', fn, 7)
    print cd.get('b', fn, 7)
7

Redisを試してみてください。これは、アプリケーションがアトミックな方法でデータを共有する最もクリーンで簡単なソリューションの1つです。セットアップが非常に簡単で、python redis client http://pypi.python.org/pypi/redis が必要です。

5
harry

問題に対する私の簡単な解決策を使用できます。それは本当に簡単で、空想的なものではありません:

class MemCache(dict):
    def __init__(self, fn):
        dict.__init__(self)
        self.__fn = fn

    def __getitem__(self, item):
        if item not in self:
            dict.__setitem__(self, item, self.__fn(item))
        return dict.__getitem__(self, item)

mc = MemCache(lambda x: x*x)

for x in xrange(10):
    print mc[x]

for x in xrange(10):
    print mc[x]

確かに有効期限機能はありませんが、MemCache c-torで特定のルールを指定することで簡単に拡張できます。

希望のコードは自明ですが、そうでない場合は、キャッシュがそのc-torパラメーターの1つとして変換関数に渡されていることは言うまでもありません。次に、入力に関するキャッシュ出力を生成するために使用されます。

それが役に立てば幸い

4

Pypiで gocept.cache を見て、タイムアウトを管理します。

2
Andreas Jung

Bda.cacheをご覧ください http://pypi.python.org/pypi/bda.cache -ZCAを使用し、zopeとbfgでテストされています。

0
Jens W. Klein