我正在實現一個實用程序庫,它是一種旨在在Google App Engine雲計算服務的分佈式環境中運行的任務管理器。 (它使用任務隊列和內存緩存的組合來執行後臺處理)。我打算使用生成器來控制任務的執行,基本上通過在用戶代碼中使用yield
來強制執行非搶先式「併發」。Python生成器在單獨函數中的「yield」
的小例子 - 處理一堆數據庫實體 - 可能是類似以下內容:
class EntityWorker(Worker):
def setup():
self.entity_query = Entity.all()
def run():
for e in self.entity_query:
do_something_with(e)
yield
我們知道,yield
是雙向溝通渠道,允許值傳遞到使用發電機代碼。這使得模擬「先發制人API」,如下面的SLEEP
電話:
def run():
for e in self.entity_query:
do_something_with(e)
yield Worker.SLEEP, timedelta(seconds=1)
但是,這是醜陋的。這將是巨大的隱藏功能獨立可能以簡單的方式調用內yield
:
self.sleep(timedelta(seconds=1))
的問題是,把yield
在功能sleep
變成它到發電機的功能。因此上面的調用將返回另一個生成器。只有再次加.next()
和yield
後,我們將獲得一個結果:
yield self.sleep(timedelta(seconds=1)).next()
這當然就更難看和不必要的冗長之前。
因此,我的問題:是否有一種方法可以將yield
轉換爲函數,而不必將其轉換爲生成器函數,但可以使其他生成器可用來生成由其計算得出的值?
'yield'使函數成爲一個生成器 - 如果它不在'self.run'中,'run'不是一個生成器,如果它在'self.sleep'中,'sleep'是一個生成器。這就是你如何在Python中定義一個生成器。所以你的問題變成了「我如何製造一臺不是發電機的發電機」或者「我怎麼不把發電機製成發電機」 - 這些都不合理。 – agf
另一個解決方案是製作自己的可迭代對象,而不是使用生成器。儘管如此,這可能會有更多的工作,並且可能沒有理由。 –