Django QuerySet和生成器

12

突然想知道使用生成器迭代结果集的以下方式是否会对正常迭代造成任何积极或消极的影响?

例如:

def all_items_generator():
  for item in Item.objects.all():
    yield item

for item in all_items_generator():
  do_stuff_with_item(item)

against:

->

反对:

for item in Item.objects.all():
  do_stuff_with_item(item)

为什么要使用生成器呢?它并没有增加任何东西。 - David Robinson
1
嗨,我在想生成器是否会对性能/资源造成任何影响? - James Lin
2个回答

24

前者会更慢,因为它会创建一个包含所有模型的列表,然后逐个生成,而后者将直接使用该列表。如果您想要一个生成器,则应该使用QuerySet.iterator()


1
你确定调用 iterator 会按照它们出现的顺序产生结果,而不仅仅是避免缓存吗?文档中并没有明确说明。 - NirIzr
@NirIzr:这两个东西有什么区别? - Ignacio Vazquez-Abrams
它可以例如创建一个结果列表并返回该列表。 我现在找到了这个:http://blog.etianen.com/blog/2013/06/08/django-querysets/,其中明确表示你是正确的。 - NirIzr
但是它们将被缓存在列表中。 - Ignacio Vazquez-Abrams
我理解缓存是为了后续查询保存结果。这不是必需的,因为调用.all()可能会(没有缓存)触发另一个DB查询。没有必要过多讨论这个问题,你的回答对我很有帮助,我已经点赞了。只是在这一部分上不太清楚,以我个人的看法。 - NirIzr

6
除了更冗长、多余且在您提供的生成器上下文中不是特别有用之外,没有其他问题。
当您在for中执行Item.objects.all()时,它们将使用iterator进行迭代,并具有查询缓存(source)。如果您不希望结果被缓存,请像Ignacio建议的那样使用iterator()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接