我试图使用Reddit API通过PRAW (https://praw.readthedocs.io/en/stable/)与Django,我正在考虑尝试使用functoolslru_cache
装饰器实现某种缓存,这样我就可以缓存类似的API调用的结果,以减少整体调用。我从来没有做过这样的事情,所以我主要遵循实现@lru_cache
装饰器的示例。
我有3个文件,主要涉及API调用/显示在这里。我:
account.html
{% extends 'myapp/base.html' %}
<h1> {{ name }} </h1>
<h3> {{ comment_karma }} </h3>
<h5> Top Posts </h5>
<table>
<tr>
<th> Post </th>
<th> Subreddit </th>
</tr>
{% for s in top_submissions %}
<tr>
<td> {{ s.title }} </td>
<td> {{ s.subreddit }} </td>
</tr>
{% endfor %}
</table>
views.py
from . import reddit
reddit = reddit.Reddit()
def account_page():
context = reddit.details(request.user.reddit_username)
return render(request, 'stats/dashboard.html', context)
reddit.py
from functools import lru_cache
class Reddit:
def __init__(self):
self.praw = praw.Reddit(
client_id = CLIENT_ID,
client_secret = CLIENT_SECRET,
user_agent = USER_AGENT
)
@lru_cache(maxsize = 256)
def details(self, redditor):
redditor = self.praw.redditor(redditor)
overview = {
'name': redditor.name,
'comment_karma': redditor.comment_karma,
'top_submissions': redditor.submissions.top(limit=10),
}
return overview
这里的问题:当我没有lru_cache,然后一切工作正常,所有的数据进来一如既往。然而,当我放置lru_cache选项时,只有名称和comment_karma出现,而提交(一个可迭代列表)只是不显示在我的页面上(所以我假设它最终没有任何值)。
我是否使用了错误的lru_cache ?从本质上讲,我的目标是,如果一个redditor
被传递到函数overview
,我不想一遍又一遍地进行相同的API调用,而是想把它放入缓存中,如果它在缓存中,则提取相同的数据。
PRAW返回惰性求值的生成器对象。你想在你的缓存函数中计算它们。否则,在生成器耗尽后,您将无法再次获得结果。
所以工作版本应该是这样的:@lru_cache(maxsize = 256)
def details(self, redditor):
redditor = self.praw.redditor(redditor)
overview = {
'name': redditor.name,
'comment_karma': redditor.comment_karma,
'top_submissions': list(redditor.submissions.top(limit=10)),
}
return overview
list(redditor.submissions.top(limit=10))
将使用生成器,缓存结果将包含列表,而不是只能使用一次的生成器对象。