【发布时间】:2023-03-13 02:57:01
【问题描述】:
我最近尝试使用 Google 搜索 foo.bar challenge。在我的时间到了之后,我决定尝试找到一个我无法解决的问题的解决方案,并找到了一个解决方案here (如果你有兴趣,包括问题陈述)。我之前一直在为我想要缓存的每个函数制作一个字典,但看起来在这个解决方案中任何函数/输入都可以使用相同的语法进行缓存。
首先,我对代码的工作方式感到困惑,*args 变量没有作为参数输入(并且什么也没有打印)。这是一个经过修改的最小示例来说明我的困惑:
mem = {}
def memoize(key, func, *args):
"""
Helper to memoize the output of a function
"""
print(args)
if key not in mem:
# store the output of the function in memory
mem[key] = func(*args)
return mem[key]
def example(n):
return memoize(
n,
lambda: longrun(n),
)
def example2(n):
return memoize(
n,
longrun(n),
)
def longrun(n):
for i in range(10000):
for j in range(100000):
2**10
return n
在这里,我使用相同的 memoize 功能,但带有打印功能。 example 函数返回 memoize(n, a lambda function,)。 longrun 函数只是一个具有大量无用计算的恒等函数,因此很容易查看缓存是否正常工作(example(2) 第一次大约需要 5 秒并且几乎是在之后)。
这是我的困惑:
- 为什么memoize的第三个参数是空的?当在 memoize 中打印 args 时,它会打印 ()。然而不知何故 mem[key] 将 func(*args) 存储为 func(key)?
- 为什么这种行为只在使用 lambda 函数时才有效(example 会缓存,而 example2 不会)?我认为 lambda: longrun(n) 只是将返回 longrun(n) 的函数作为输入提供的一种简短方式。
作为奖励,有人知道如何使用装饰器来记忆函数吗?
我也想不出一个更具描述性的标题,欢迎编辑。谢谢。
【问题讨论】:
-
请参阅文档并使用搜索。
*argsnotation provides variadic arguments。由于您没有提供任何参数,*args是空的。example2不起作用,因为你没有提供函数,你提供了调用函数的结果。它应该是memoize(n, longrun, n)。 -
感谢@janbrohl,这正是我所追求的装饰器!