当前位置:  开发笔记 > 编程语言 > 正文

有一个Python缓存库吗?

如何解决《有一个Python缓存库吗?》经验,为你挑选了9个好方法。

我正在寻找一个Python缓存库,但到目前为止找不到任何东西.我需要一个dict类似于简单的界面,我可以设置密钥及其过期,并让它们重新缓存.类似的东西:

cache.get(myfunction, duration=300)

如果它存在,它将从缓存中提供该项目,或者如果它没有或已经过期,则调用该函数并存储它.有谁知道这样的事情?



1> 小智..:

从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)


[cachetools](https://pypi.python.org/pypi/cachetools)提供了很好的实现,它兼容python 2和python 3.

2> Corbin March..:

看看Beaker:

主页

缓存文档

关于将Beaker与Django一起使用的好快速入门文章(但在任何其他应用程序中也很有用)


另见[dogpile](https://bitbucket.org/zzzeek/dogpile.cache) - 据说是新的和改进的烧杯.

3> tgray..:

您还可以查看Memoize装饰器.你可以在没有太多修改的情况下让它做你想做的事.



4> j13r..:

Joblib http://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


作为旁注,当您使用大型NumPy数组时,joblib确实很有用,因为它具有特殊的方法来处理它们.

5> NuclearPeon..:

还没有人提到搁置.https://docs.python.org/2/library/shelve.html

它不是memcached,但看起来更简单,可能适合您的需要.



6> David Berger..:

我认为python memcached API是流行的工具,但我自己并没有使用它,也不确定它是否支持你需要的功能.


那个是行业标准,但我想要的只是一个简单的内存存储机制,可以容纳100个左右的密钥,而memcached有点矫枉过正.谢谢你的回答.

7> Tzury Bar Yo..:
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 '' % (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 __name__ == '__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)


我做了类似的事情,但你需要多线程锁和大小参数来避免它无限增长.然后你需要一些函数来通过访问来对密钥进行排序,以丢弃访问量最少的密钥等等......

8> harry..:

尝试使用redis,它是应用程序以原子方式共享数据或者如果您有一些Web服务器平台的最简洁和最简单的解决方案之一.它很容易设置,你需要一个python redis客户端http://pypi.python.org/pypi/redis



9> 小智..:

您可以使用我的简单解决方案来解决该问题。这真的很简单,没有花哨:

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参数之一传递给翻译函数。依次用于生成有关输入的缓存输出。

希望能帮助到你

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有