簡體   English   中英

生成器的惰性Python行為

[英]Lazy Python behavior with generators

好的,馬上開始:我知道Python生成器是惰性的。 話雖如此,這真讓我震驚。 我不明白 Python朋友,請不要因為這個問題的無知而將我釘在十字架上。 在現實世界的開發情況中並沒有遇到這種情況,只是好奇心一直困擾着我。

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

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

print(gen2(gen1(0)))

該示例完全按照我的期望進行操作,先輸出gen1然后gen2然后2。

以下代碼示例不包含:

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

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

print(list(gen2(gen1(0))))

相反,它僅打印“ gen2”和[2]。 因此,等待一秒鍾,它首先調用gen2嗎? 它從不評估gen1嗎? 什么?! 在引擎蓋下,它如何將魔鬼拉下來? 這里實際上發生了什么? 因此,最外層的事物被識別為生成器,並且觸發了一些內省,這些內省表明不需要對內部生成器進行評估? 跟蹤此行為的更有用的方法是什么?

生成器中的代碼不是在創建生成器時執行的,而是在被諸如循環,理解或其他生成器之類的驅動結構所使用時執行的。 以下內容可能會清除此問題:

>>> 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該函數是一個生成器函數,其主體在調用時不會執行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM