好的,马上就开始了:我知道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?什么?!在引擎盖下,它如何将魔鬼魔法拉下来?这里到底发生了什么?因此,最外层的东西被识别为一个生成器,它会触发一些内省,以确定内部生成器的评估是不必要的?什么是追踪此行为的更具信息性的方式?
答案 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
该函数是生成器函数被召唤时身体不被执行。