有Python缓存库吗?

问题:有Python缓存库吗?

我正在寻找Python缓存库,但到目前为止找不到任何东西。我需要一个简单dict的类似接口,可以在其中设置密钥及其有效期,并将其重新缓存。有点像:

cache.get(myfunction, duration=300)

它将从缓存中为我提供该项目(如果存在),或者调用该函数并将其存储(如果它不存在或已过期)。有人知道这样吗?

I’m looking for a Python caching library but can’t find anything so far. I need a simple dict-like interface where I can set keys and their expiration and get them back cached. Sort of something like:

cache.get(myfunction, duration=300)

which will give me the item from the cache if it exists or call the function and store it if it doesn’t or has expired. Does anyone know something like this?


回答 0


回答 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)

From Python 3.2 you can use the decorator @lru_cache from the functools library. It’s a Last Recently Used cache, so there is no expiration time for the items in it, but as a fast hack it’s very useful.

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)

回答 2

您还可以查看Memoize装饰器。您可能无需做太多修改就可以使它完成您想做的事情。

You might also take a look at the Memoize decorator. You could probably get it to do what you want without too much modification.


回答 3

Joblib https://joblib.readthedocs.io支持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装饰器。该文档位于此处:https : //joblib.readthedocs.io/en/latest/generation/joblib.Memory.html

Joblib https://joblib.readthedocs.io supports caching functions in the Memoize pattern. Mostly, the idea is to cache computationally expensive functions.

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

You can also do fancy things like using the @memory.cache decorator on functions. The documentation is here: https://joblib.readthedocs.io/en/latest/generated/joblib.Memory.html


回答 4

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

它不是memcached的,但是看起来更简单,并且可能满足您的需求。

No one has mentioned shelve yet. https://docs.python.org/2/library/shelve.html

It isn’t memcached, but looks much simpler and might fit your need.


回答 5

我认为python memcached API是流行的工具,但我自己并未使用过它,也不确定它是否支持您所需的功能。

I think the python memcached API is the prevalent tool, but I haven’t used it myself and am not sure whether it supports the features you need.


回答 6

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

回答 7

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

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

希望能帮助到你

You can use my simple solution to the problem. It is really straightforward, nothing fancy:

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]

It indeed lacks expiration funcionality, but you can easily extend it with specifying a particular rule in MemCache c-tor.

Hope code is enough self-explanatory, but if not, just to mention, that cache is being passed a translation function as one of its c-tor params. It’s used in turn to generate cached output regarding the input.

Hope it helps


回答 8

尝试使用redis,它是应用程序以原子方式共享数据或如果您具有某种Web服务器平台的最干净,最简单的解决方案之一。它非常容易设置,您将需要一个python redis客户端http://pypi.python.org/pypi/redis

Try redis, it is one of the cleanest and easiest solutions for applications to share data in a atomic way or if you have got some web server platform. Its very easy to setup, you will need a python redis client http://pypi.python.org/pypi/redis


回答 9

查看pypi 上的gocept.cache,管理超时。

Look at gocept.cache on pypi, manage timeout.


回答 10

项目旨在提供“为人类提供缓存”(尽管似乎相当未知)

来自项目页面的一些信息:

安装

点安装缓存

用法:

import pylibmc
from cache import Cache

backend = pylibmc.Client(["127.0.0.1"])

cache = Cache(backend)

@cache("mykey")
def some_expensive_method():
    sleep(10)
    return 42

# writes 42 to the cache
some_expensive_method()

# reads 42 from the cache
some_expensive_method()

# re-calculates and writes 42 to the cache
some_expensive_method.refresh()

# get the cached value or throw an error
# (unless default= was passed to @cache(...))
some_expensive_method.cached()

This project aims to provide “Caching for humans” (seems like it’s fairly unknown though)

Some info from the project page:

Installation

pip install cache

Usage:

import pylibmc
from cache import Cache

backend = pylibmc.Client(["127.0.0.1"])

cache = Cache(backend)

@cache("mykey")
def some_expensive_method():
    sleep(10)
    return 42

# writes 42 to the cache
some_expensive_method()

# reads 42 from the cache
some_expensive_method()

# re-calculates and writes 42 to the cache
some_expensive_method.refresh()

# get the cached value or throw an error
# (unless default= was passed to @cache(...))
some_expensive_method.cached()

回答 11

查看bda.cache http://pypi.python.org/pypi/bda.cache-使用ZCA并经过zope和bfg的测试。

Look at bda.cache http://pypi.python.org/pypi/bda.cache – uses ZCA and is tested with zope and bfg.


回答 12

keyring是最好的python缓存库。您可以使用

keyring.set_password("service","jsonkey",json_res)

json_res= keyring.get_password("service","jsonkey")

json_res= keyring.core.delete_password("service","jsonkey")

keyring is the best python caching library. You can use

keyring.set_password("service","jsonkey",json_res)

json_res= keyring.get_password("service","jsonkey")

json_res= keyring.core.delete_password("service","jsonkey")