До Python3.5: генераторы
Это решение также работает для более поздних версий Python, хотя async def
, новое в Python3.5, кажется более подходящим для вашего варианта использования. См. Следующий раздел .
Значения, полученные генератором, получены путем итерации или с использованием next
. Значение, возвращаемое в конце, сохраняется в атрибуте value
исключения StopIteration
, которое указывает конец генератора. К счастью, это не так сложно восстановить.
def hardWork():
output = []
for i in range(10):
# hard work
yield 'Doing ' + str(i)
output.append(i ** 2)
return output
def generator():
# do some calculations
work = hardWork()
while True:
try:
print(next(work))
except StopIteration as e:
result = e.value
break
yield result
Пример
foo = generator()
print(next(foo))
выход
Doing 0
Doing 1
Doing 2
Doing 3
Doing 4
Doing 5
Doing 6
Doing 7
Doing 8
Doing 9
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Python3.5 +: async def
Если вы работаете с Python3.5 +, то, что вы пытаетесь, кажется, идеально подходит для цикла обработки событий с использованием ожидаемых функций.
import asyncio
async def hardWork():
output = []
for i in range(10):
# do hard work
print('Doing ', i)
output.append(i**2)
# Break point to allow the event loop to do other stuff on the side
await asyncio.sleep(0)
return output
async def main():
result = await asyncio.wait_for(hardWork(), timeout=None)
print(result)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
выход
Doing 0
Doing 1
Doing 2
Doing 3
Doing 4
Doing 5
Doing 6
Doing 7
Doing 8
Doing 9
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]