gpt4 book ai didi

python - 带有默认可选参数的内存/缓存

转载 作者:行者123 更新时间:2023-12-04 01:55:21 31 4
gpt4 key购买 nike

我想制作一个 python 装饰器来内存函数。例如,如果

@memoization_decorator    
def add(a, b, negative=False):
print "Computing"
return (a + b) * (1 if negative is False else -1)

add(1, 2)
add(1, b=2)
add(1, 2, negative=False)
add(1, b=2, negative=False)
add(a=1, b=2, negative=False)
add(a=1, b=2)

我希望输出是

Computing
3
3
3
3
3
3

并且在最后 6 行的任何排列下输出都应该相同。

这相当于找到一个映射,将等效的 *args, **kwargs** 集发送到内存缓存 dict 的唯一键。上面的例子有 *args, **kwargs 等于

(1, 2), {}
(1,), {'b': 2}
(1, 2), {'negative': False}
(1,), {'b': 2, 'negative': False}
(), {'a': 1, 'b': 2, 'negative': False}
(), {'a': 1, 'b': 2}

最佳答案

对于内存,您可以使用 functools.lru_cache() .

编辑:您的用例的问题在于,如果指定参数的方式不同,它不会将两个函数调用视为相同。为了解决这个问题,我们可以编写自己的装饰器,它位于 lru_cache() 之上,并将参数转换为单一的规范形式:

from functools import lru_cache, wraps
import inspect

def canonicalize_args(f):
"""Wrapper for functools.lru_cache() to canonicalize default
and keyword arguments so cache hits are maximized."""

@wraps(f)
def wrapper(*args, **kwargs):
sig = inspect.getfullargspec(f.__wrapped__)

# build newargs by filling in defaults, args, kwargs
newargs = [None] * len(sig.args)
newargs[-len(sig.defaults):] = sig.defaults
newargs[:len(args)] = args
for name, value in kwargs.items():
newargs[sig.args.index(name)] = value

return f(*newargs)

return wrapper

@canonicalize_args
@lru_cache()
def add(a, b, negative=False):
print("Computing")
return (a + b) * (1 if negative is False else -1)

现在 add() 只对问题中的整个调用集调用一次。每次调用都是根据位置指定的所有三个参数进行的。

关于python - 带有默认可选参数的内存/缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36771866/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com