我可以记住 Python 生成器吗?
我有一个名为 runquery
的函数,它调用数据库,然后逐一生成行。我写了一个memoize装饰器(或者更准确地说,我只是从这个stackoverflow问题中偷了一个)但是在后续调用中,它只会产生一个空序列,大概是因为生成器的值只能产生一次。
如何修改适用于 Python 生成器的记忆装饰器?我意识到我需要在某个时候将它存储在内存中,但我想在装饰器中处理这个问题而不是修改原始函数。
记忆功能的当前代码是:
def memoized(f):
# Warning: Doesn't work if f yields values
cache={}
def ret(*args):
if args in cache:
return cache[args]
else:
answer=f(*args)
cache[args]=answer
return answer
return ret
I have a function called runquery
that makes calls to a database and then yields the rows, one by one. I wrote a memoize decorator (or more accurately, I just stole one from this stackoverflow question) but on subsequent calls it just yields an empty sequence, presumably because a generator's values can only be yielded once.
How could I modify the memoization decorator that works for Python generators? I realise I will need to store it in memory at some point but I'd like to handle this within the decorator and not modify the original function.
The current code of the memoization function is:
def memoized(f):
# Warning: Doesn't work if f yields values
cache={}
def ret(*args):
if args in cache:
return cache[args]
else:
answer=f(*args)
cache[args]=answer
return answer
return ret
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我意识到这是一个老问题,但对于那些想要完整解决方案的人来说:这是一个基于 jsbueno 的建议的问题:
I realise this is somewhat of an old question, but for those who want a full solution: here's one, based on jsbueno's suggestion:
完毕。
对于生成器来说更容易,因为标准库有这个“tee”方法!
Done.
It is easier for generators because the standard lib has this "tee" method!
是的。 此处发布了一个装饰器。请注意,正如海报所说,您会失去一些惰性评估的好处。
Yes. There's a decorator posted here. Take note that as the poster says, you lose some of the benefit of lazy evaluation.
与其他答案类似,但如果您知道 f 是生成器,则更简单:
Similar to the other answers, but simpler if you know that
f
is a generator: