python – 為什麼在使用具有asyncio的協同程式列表解析時得到不同的結果?
我最初有一些程式碼將結果彙總到列表中.當我重構這個程式碼來使用列表構成時,我得到了意想不到的結果:
import asyncio @asyncio.coroutine def coro(): return "foo" # Writing the code without a list comp works, # even with an asyncio.sleep(0.1). @asyncio.coroutine def good(): yield from asyncio.sleep(0.1) result = [] for i in range(3): current = yield from coro() result.append(current) return result # Using a list comp without an async.sleep(0.1) # works. @asyncio.coroutine def still_good(): return [(yield from coro()) for i in range(3)] # Using a list comp along with an asyncio.sleep(0.1) # does _not_ work. @asyncio.coroutine def huh(): yield from asyncio.sleep(0.1) return [(yield from coro()) for i in range(3)] loop = asyncio.get_event_loop() print(loop.run_until_complete(good())) print(loop.run_until_complete(still_good())) print(loop.run_until_complete(huh()))
如果我執行這個程式碼,我得到這個輸出:
$<a href="https://codeday.me/tag/python">Python</a>3.4 /tmp/test.py ['foo', 'foo', 'foo'] ['foo', 'foo', 'foo'] <generator object <listcomp> at 0x104eb1360>
為什麼我會獲得第三個huh()函式的不同結果?
解決問題的方法是將next(…)代替…返回第三個函式,或者更好地為範圍(3)中的i返回列表((coro()的yield)()對於這個想法來說,@zch的信用),或者更好的保持第一個功能.
關鍵是第二個函式不是發生器.它只是一個普通的函式,返回一個理解生成器.
例如,此程式碼在生成器外部有效:
values = [(yield x) for x in range(3)]
那麼你可以這樣做:
next(values) 0 next(values) 1 next(values) 2 next(values) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration: [None, None, None]
裝飾器@coroutine然後通過迭代結果使第二個函式成為一個生成器,參見ofollow,noindex" target="_blank">here ,第143行.
相比之下,第一個和第三個函式實際上是生成器,而@coroutine裝飾器只返回自己,參見here ,第136-137行.在第一種情況下,生成器返回列表(實際引發StopIteration([‘foo’,’foo’,’foo’])).在第三種情況下,它返回理解產生器.
程式碼日誌版權宣告:
翻譯自:http://stackoverflow.com/questions/29334054/why-am-i-getting-different-results-when-using-a-list-comprehension-with-coroutin