Pythonキャッシングライブラリを探していますが、これまでのところ何も見つかりません。キーとその有効期限を設定して取得できるシンプルなdict
のようなインターフェイスが必要です。バックキャッシュされます。
cache.get(myfunction, duration=300)
存在する場合はキャッシュからアイテムを取得します。存在しない場合や期限切れの場合は関数を呼び出して保存します。誰かがこのようなことを知っていますか?
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)
Memoize decorator もご覧ください。おそらく、あまり変更を加えなくても、必要な処理を実行できます。
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
誰もまだ棚について言及していません。 https://docs.python.org/2/library/shelve.html
Memcachedではありませんが、よりシンプルに見え、ニーズに合うかもしれません。
python memcached API は一般的なツールですが、自分で使用したことはなく、必要な機能をサポートしているかどうかはわかりません。
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)
Redisを試してみてください。これは、アプリケーションがアトミックな方法でデータを共有する最もクリーンで簡単なソリューションの1つです。セットアップが非常に簡単で、python redis client http://pypi.python.org/pypi/redis が必要です。
問題に対する私の簡単な解決策を使用できます。それは本当に簡単で、空想的なものではありません:
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つとして変換関数に渡されていることは言うまでもありません。次に、入力に関するキャッシュ出力を生成するために使用されます。
それが役に立てば幸い
Pypiで gocept.cache を見て、タイムアウトを管理します。
Bda.cacheをご覧ください http://pypi.python.org/pypi/bda.cache -ZCAを使用し、zopeとbfgでテストされています。