を__aiter__
存在しないことを言います)はPython 3.5で導入されました。 py3.4の場合、最も近いのはasyncio.gatherです(すべてのタスクを同時に実行するか、すべて終了するまで待ちます)。または結果をasyncio.Queue(順番に、async for
)にプッシュします。編集:質問に記載されているasync for
代替の最後の例を参照してください。ここで
はasyncio.gatherのためのpythonのドキュメントALA例です。
import asyncio
@asyncio.coroutine
def task(id):
print("task: {}".format(id))
yield from asyncio.sleep(random.uniform(1, 3))
return id
tasks = [
task("A"),
task("B"),
task("C")
]
loop = asyncio.get_event_loop()
results = loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
print(results)
出力:
task: B
task: A
task: C
['A', 'B', 'C']
ここではasyncio.Queueするためのものである:
import asyncio
@asyncio.coroutine
def produce(queue, n):
for x in range(n):
print('producing {}/{}'.format(x, n))
# todo: do something more useful than sleeping :)
yield from asyncio.sleep(random.random())
yield from queue.put(str(x))
@asyncio.coroutine
def consume(queue):
while True:
item = yield from queue.get()
print('consuming {}...'.format(item))
# todo: do something more useful than sleeping :)
yield from asyncio.sleep(random.random())
queue.task_done()
@asyncio.coroutine
def run(n):
queue = asyncio.Queue()
# schedule the consumer
consumer = asyncio.ensure_future(consume(queue))
# run the producer and wait for completion
yield from produce(queue, n)
# wait until the consumer has processed all items
yield from queue.join()
# the consumer is still awaiting for an item, cancel it
consumer.cancel()
loop = asyncio.get_event_loop()
loop.run_until_complete(run(10))
loop.close()
編集:async for
質問に記載されている代替:
import asyncio
import random
class StopAsyncIteration(Exception):
""""""
class MyCounter:
def __init__(self, count):
self.count = count
def __aiter__(self):
return self
@asyncio.coroutine
def __anext__(self):
if not self.count:
raise StopAsyncIteration
return (yield from self.do_something())
@asyncio.coroutine
def do_something(self):
yield from asyncio.sleep(random.uniform(0, 1))
self.count -= 1
return self.count
@asyncio.coroutine
def getNumbers():
i = MyCounter(10).__aiter__()
while True:
try:
row = yield from i.__anext__()
except StopAsyncIteration:
break
else:
print(row)
loop = asyncio.get_event_loop()
loop.run_until_complete(getNumbers())
loop.close()
(のような通常無効値:None
、""
、-1
など)を行うときは、この__aiter__
と__anext__
の両方を除去しdo_something
方法自体の中に停止例外を上げることによって簡略化またはセンチネル結果を返すことができることに注意してください
作業中のPython 3.5コードをお持ちの場合は、 '.__ aiter __()'と '.__ anext __()'メソッドのソースを見てください(ITERごとに異なる場合があります)。 – jfs
@ OldBunny2800私はあなたがこれを探していると信じていますhttps://stackoverflow.com/questions/30191556/coroutine-in-python-between-3-4-and-3-5-how-can-i-keep-backwords-互換性 –