【问题标题】:Caching for special calls缓存特殊呼叫
【发布时间】:2021-01-16 16:00:48
【问题描述】:

如何将装饰器 lru_cachefunctools 更改为具有指示是否缓存此调用的标志。
例如

@new_lru_cache
def f(args, kwargs):
    ...body function...

f(1) # not saved
f(2, cache=True) # saved

【问题讨论】:

  • 你有没有尝试过,做过什么研究?
  • 添加尝试......

标签: python python-3.x python-decorators functools


【解决方案1】:

考虑一下 - lru_cache 的扩展,允许访问以配置缓存。

from functools import lru_cache

def controlled_lru_cache(*lru_args, **lru_kwargs):
    def decorator(func):
        func_with_cache = lru_cache(*lru_args, **lru_kwargs)(func)
        def decorated(*args, cache=False, **kwargs):
            if cache:
                return func_with_cache(*args, **kwargs) 
            return func(*args, **kwargs)
        return decorated
    return decorator

@controlled_lru_cache(maxsize=64)
def square(n):
    return n * n

【讨论】:

    【解决方案2】:

    如果你要为它编写一个完整的函数,为什么不复制粘贴原始源代码并在那里实现你的逻辑?

    def lru_cache(maxsize=128, typed=False, cache=False):
        if isinstance(maxsize, int):
            if maxsize < 0:
                maxsize = 0
        elif callable(maxsize) and isinstance(typed, bool):
            user_function, maxsize = maxsize, 128
            wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
            return update_wrapper(wrapper, user_function)
        elif maxsize is not None:
            raise TypeError('Expected first argument to be an integer, a callable, or None')
    
        def decorating_function(user_function):
            if not cache:
                return user_function # We add here
            wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)
            return update_wrapper(wrapper, user_function)
    
        return decorating_function
    

    通过这种方式,您可以更好地控制函数,并且可以轻松查看所有内容,并且可以通过这种方式玩转 functools 的内部。

    【讨论】:

      【解决方案3】:

      我自己做的。

      def new_lru_cache(f):
          g = None
          def inner(*args, cache=False, **kwargs):
              if cache:
                  nonlocal g
                  if g is None:
                      g = lru_cache(f)
                  return g(*args, **kwargs)
              else:
                  return f(*args, **kwargs)
          return inner
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-30
        • 2015-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多