Как сделать так, чтобы задание / сопрограмма возвращало значения, которые должны быть назначены - PullRequest
0 голосов
/ 21 апреля 2019

TL; DR: Я хочу создать задачу / сопрограмму asyncio и получить возвращаемые значения, которые будут назначены в переменной.

-

Я нашел этот вопрос Получение значений из функций, которые выполняются как асинхронные задачи Который кажется говорит о подобной проблеме, но синтаксис сильно изменился в модуле asyncio, что я даже не уверен, связано ли это. [ Я на Python 3.7.2 ]

Пример кода для объяснения того, что я пытаюсь сделать:

async def s(f):
    func = {
        1: op1,
        2: op2,
        3: op3
      }.get(f,False)
    var = func(f)
    return var

def op1(f):
    print('Op1',f+f)
    return f+f

def op2(f):
    print('Op2', f*f)
    return f*f

def op3(f):
    print('Op3', f**f)
    return f**f

async def main():
    task1 = asyncio.create_task(s(1))
    task2 = asyncio.create_task(s(3))
    print(f"started at {time.strftime('%X')}")
    await task1
    await task2
    print(task1,task2)
    print(f"finished at {time.strftime('%X')}")

Функция main () является примером сопрограммы из документов https://docs.python.org/3/library/asyncio-task.html#coroutines

Предполагается, что s () будет переключателем, который выберет правильную функцию (одну из op1, op2, op3) для сценария, запустит функцию и вернет результат (из того, что я ожидал) для назначения task1 / task2.

То, что фактически назначено для задачи 1 / задачи 2:

<Task finished coro=<s() done, defined at C:\...\test.py:17> result=2> 
<Task finished coro=<s() done, defined at C:\...\test.py:17> result=27>

Как видите, возвращаемый результат сохраняется в 'result' (атрибут? Var?), Но не присваивается напрямую переменной.

Мне нужно либо: назначить возврат непосредственно в переменную ИЛИ способ получить доступ к «результату» и назначить его в переменную, где я могу далее манипулировать.

Кстати: print(task1.result) возвращает это: <built-in method result of _asyncio.Task object at 0x0000028592DDA048>

1 Ответ

1 голос
/ 21 апреля 2019
async def main():
    task1 = asyncio.create_task(s(1))
    task2 = asyncio.create_task(s(3))
    print(f"started at {time.strftime('%X')}")
    result_of_task1 = await task1
    result_of_task2 = await task2
    print(result_of_task1,result_of_task2)
    print(f"finished at {time.strftime('%X')}")

- это один из способов сделать это.Я предпочитаю это, так как ожидание задач больше похоже на обычные вызовы функций, но также эквивалентен

await task1
# some time later
result_of_task1 = task1.result()

Вы только что пропустили (), потому что результатом является метод, а не переменная-член.

...