在python中使用时间限制缓存内存 [英] Caching in-memory with a time limit in python

查看:488
本文介绍了在python中使用时间限制缓存内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个返回列表的函数,例如list_x。

I have a function that returns a list, say list_x.

def result(val):
    ..
    return(list_x)

我每分钟都调用result()并存储列表

I am calling result() every minute and storing the list.

def other_func():
    #called every minute
    new_list = result(val)

我想将new_list的值存储一个小时(在某种形式的内存缓存中?),然后再次进行更新,基本上是一个小时后而不是每分钟调用一次result()。我读到有关functools.lru_cache的信息,但这对我没有帮助。有任何想法吗?

I would like to store the value of new_list for an hour (in some sort of in-memory cache may be?) and then update it again, basically call results() after an hour and not every minute.I read about functools.lru_cache but that will not help here I think. Any ideas?

推荐答案

构建具有生存时间的单元素缓存非常简单:

Building a single-element cache with a time-to-live is pretty trivial:

_last_result_time = None
_last_result_value = None
def result(val):
    global _last_result_time
    global _last_result_value
    now = datetime.datetime.now()
    if not _last_result_time or now - _last_result_time > datetime.timedelta(hours=1):
        _last_result_value = <expensive computation here>
        _last_result_time = now
    return _last_result_value

如果要将其概括为装饰器,这并不难:

If you want to generalize this as a decorator, it's not much harder:

def cache(ttl=datetime.timedelta(hours=1)):
    def wrap(func):
        time, value = None, None
        @functools.wraps(func)
        def wrapped(*args, **kw):
            nonlocal time
            nonlocal value
            now = datetime.datetime.now()
            if not time or now - time > ttl:
                value = func(*args, **kw)
                time = now
            return value
        return wrapped
    return wrap

如果您希望它处理不同的参数,则为每个参数存储生存时间:

If you want it to handle different arguments, storing a time-to-live for each one:

def cache(ttl=datetime.timedelta(hours=1)):
    def wrap(func):
        cache = {}
        @functools.wraps(func)
        def wrapped(*args, **kw):
            now = datetime.datetime.now()
            # see lru_cache for fancier alternatives
            key = tuple(args), frozenset(kw.items()) 
            if key not in cache or now - cache[key][0] > ttl:
                value = func(*args, **kw)
                cache[key] = (now, value)
            return cache[key][1]
        return wrapped
    return wrap

当然,您可以为其添加关键功能-为其提供最大尺寸和通过存储时间或通过LRU或其他任何所需的方式逐出,将缓存统计信息公开为修饰函数上的属性,等等。 lru_cache 应该会帮助您了解如何完成大多数棘手的事情(自它几乎完成了所有操作。)

You can of course key adding features to it—give it a max size and evict by time of storage or by LRU or whatever else you want, expose cache stats as attributes on the decorated function, etc. The implementation of lru_cache in the stdlib should help show you how to do most of the trickier things (since it does almost all of them).

这篇关于在python中使用时间限制缓存内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆