考慮這兩個功能:爲什麼不能用kwarg切換函數發生器的行爲?
def foo():
x = 0
while True:
yield x
x += 1
def wrap_foo(limit=10, gen=True):
fg = foo()
count = 0
if gen:
while count < limit:
yield next(fg)
count += 1
else:
return [next(fg) for _ in range(limit)]=
foo()
是發電機,並wrap_foo()
只是把多少數據獲取生成的限制。我正在嘗試讓包裝器像gen=True
一樣生成一個生成器,或者作爲一個常規函數,將所有生成的數據直接與kwarg gen=False
一起存儲到內存中。
經常發生的行爲可以作爲我期望:
In [1352]: [_ for _ in wrap_foo(gen=True)]
Out[1352]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
然而,隨着gen=False
說,沒有東西產生。
In [1351]: [num for num in wrap_foo(gen=False)]
Out[1351]: []
好像Python的預分類的功能以基於yield
語句的存在的發電機(後者例如,如果yield
被註釋了完美地工作)。
這是爲什麼?我想了解這裏的機制。我跑3.6
如果在你的'def'中有一個'yield',那麼這個函數將永遠是一個生成器*。一個'return'將作爲一個隱含的'StopIteration',而不是一個典型的'return'值。如果你想把整個東西加載到內存中,只需使用'list(wrap_foo(10))'。你爲什麼要以其他方式來做? –
這就是我的想法。我只是在我的交互式shell中一度懶惰,並試圖添加一個kwarg,所以我可以直接獲取生成的數據,而不是總是調用'[_ for _ in ...'然後我有些奇怪,爲什麼我不能去做。 –
但是你不需要*調用'[_ for _ in ...]',你已經將該邏輯抽象爲一個生成器,所以要實現它只是使用'list' –