![](/img/trans.png)
[英]Python: async generator returned from intermediate function raising TypeError
[英]Generator returned from function completes prematurely
我有以下代碼來復用阻塞生成器:
import datetime
import time
import queue
import threading
def blocking1():
while True:
time.sleep(1)
result = "Block1: {}".format(datetime.datetime.now())
yield result
def blocking2():
while True:
time.sleep(2)
result = "Block2: {}".format(datetime.datetime.now())
yield result
def multiplex(generators):
if len(generators) == 1:
return generators[0]
elif len(generators) > 1:
q = queue.Queue()
def run_one(src):
for e in src: q.put(e)
def run_all():
threads = []
for src in generators:
t = threading.Thread(target=run_one, args=(src,))
t.start()
threads.append(t)
for t in threads: t.join()
q.put(StopIteration)
threading.Thread(target=run_all).start()
while True:
e = q.get()
if e is StopIteration:
return
yield e
else:
return []
if __name__ == "__main__":
# tasks = [("map1: {}".format(e) for e in blocking1()), ("map2: {}".format(e) for e in blocking2())]
tasks = [("map1: {}".format(e) for e in blocking1())]
for e in multiplex(tasks):
print(e)
我想聰明一點,如果只有一個生成器,不要進行任何線程生成。 只需返回這個單一的生成器(在所有類型仍然匹配之后)
然而,它不是那樣工作的。
程序立即終止(就像這是空生成器)
有趣的是以下作品(顯示了map1...
輸出):
import datetime
import time
import queue
import threading
def blocking1():
while True:
time.sleep(1)
result = "Block1: {}".format(datetime.datetime.now())
yield result
def blocking2():
while True:
time.sleep(2)
result = "Block2: {}".format(datetime.datetime.now())
yield result
def multiplex(generators):
if len(generators) == 1:
return generators[0]
else:
return []
if __name__ == "__main__":
# tasks = [("map1: {}".format(e) for e in blocking1()), ("map2: {}".format(e) for e in blocking2())]
tasks = [("map1: {}".format(e) for e in blocking1())]
for e in multiplex(tasks):
print(e)
區別僅在於刪除了elif
部分...
有人可以幫我理解發生了什么嗎? 我正在使用 Python 3.5.3
您不能(有用地)從在其主體中的任何地方也執行yield
的函數返回值(即使return
和yield
出現在永遠不會在函數的同一執行期間運行的單獨代碼塊中)。 如果您在函數的任何地方都有一個yield
,那么您正在創建一個生成器函數而不是一個普通的函數。
一個很好的解決方法是,如果您只獲得一個生成器, yield from
您的單獨生成器中產生:
def multiplex(generators):
if len(generators) == 1:
yield from generators[0] # because this is a generator function, we need to yield here
elif len(generators) > 1:
... # there's a yield in here causing the whole thing to be a generator function!
問題是您要返回一個生成器,而不是對其進行迭代。
代替
return generators[0]
和
yield from generators[0]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.