【问题标题】:Make @lru_cache ignore some of the function arguments使@lru_cache 忽略一些函数参数
【发布时间】:2015-08-24 05:00:21
【问题描述】:

如何让@functools.lru_cache 装饰器忽略一些关于缓存键的函数参数?

例如,我有一个如下所示的函数:

def find_object(db_handle, query):
    # (omitted code)
    return result

如果我像这样应用lru_cache 装饰器,db_handle 将包含在缓存键中。结果,如果我尝试使用相同的query,但不同的db_handle 调用该函数,它将再次执行,我想避免这种情况。我希望 lru_cache 仅考虑 query 参数。

【问题讨论】:

    标签: python caching python-decorators lru functools


    【解决方案1】:

    cachetools 你可以写:

    from cachetools import cached
    from cachetools.keys import hashkey
    
    from random import randint
    
    @cached(cache={}, key=lambda db_handle, query: hashkey(query))
    def find_object(db_handle, query):
        print("processing {0}".format(query))
        return query
    
    queries = list(range(5))
    queries.extend(range(5))
    for q in queries:
        print("result: {0}".format(find_object(randint(0, 1000), q)))
    

    【讨论】:

    • 您能否详细说明一下这个答案,key 和 hashkey 是什么?
    【解决方案2】:

    我至少有一个非常难看的解决方案。将db_handle 包裹在一个始终等于的对象中,然后在函数中解包。

    它需要一个带有很多辅助函数的装饰器,这使得堆栈跟踪非常混乱。

    class _Equals(object):
        def __init__(self, o):
            self.obj = o
    
        def __eq__(self, other):
            return True
    
        def __hash__(self):
            return 0
    
    def lru_cache_ignoring_first_argument(*args, **kwargs):
        lru_decorator = functools.lru_cache(*args, **kwargs)
    
        def decorator(f):
            @lru_decorator
            def helper(arg1, *args, **kwargs):
                arg1 = arg1.obj
                return f(arg1, *args, **kwargs)
    
            @functools.wraps(f)
            def function(arg1, *args, **kwargs):
                arg1 = _Equals(arg1)
                return helper(arg1, *args, **kwargs)
    
            return function
    
        return decorator
    

    【讨论】:

      猜你喜欢
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-18
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多