使用生成器的惰性Python行为

时间:2018-01-28 00:08:38

标签: python generator

好的,马上就开始了:我知道Python生成器是懒惰的。那说,这让我大吃一惊;我不明白。 Pythonic的朋友们,请不要因为对这个问题的无知而把我钉在十字架上。这在现实世界的发展情况中并没有遇到,只是一直困扰着我的好奇心。

data grid view

这个样本完全符合我的预期,它打印gen1然后gen2然后2。

以下代码示例不会:

def gen1(n):
    print('gen1')
    return 1

def gen2(n):
    print('gen2')
    return 2

print(gen2(gen1(0)))

相反,它只是打印'gen2'和[2]。所以等待一个热点,它先调用gen2?它永远不会评估gen1?什么?!在引擎盖下,它如何将魔鬼魔法拉下来?这里到底发生了什么?因此,最外层的东西被识别为一个生成器,它会触发一些内省,以确定内部生成器的评估是不必要的?什么是追踪此行为的更具信息性的方式?

1 个答案:

答案 0 :(得分:1)

生成器中的代码在创建生成器时不会执行,但是当它被驱动构造(如循环,理解或其他生成器)使用时。以下内容可能会清除这一点:

>>> def gen1(n):
...     print('gen1')
...     yield 1
...     print('gen1')
...     yield 2
... 
>>> g = gen1(5)  
# this returns the generator object, 
# but does not execute any code in it, hence 'lazy'
>>> for x in g:  
        # each 'x' assignment executes code til the next 'yield'
...     print x
... 
gen1
1
gen1
2

您可能想知道程序在第一个yield语句之前是如何知道它是一个生成器,但解释器首先检查整个函数体,如果有yield该函数是生成器函数被召唤时身体不被执行。