Python asyncio.gather возвращает Future, прикрепленный к другому исключению циклаPython

Программы на Python
Ответить
Anonymous
 Python asyncio.gather возвращает Future, прикрепленный к другому исключению цикла

Сообщение Anonymous »

Я использую Python 3.13.2.
Здесь я просматриваю руководство по Python asyncio. Примерно в 10:20 преподаватель показывает пример asyncio.gather с сопрограммой, принимающей Future.
Вот пример кода, который у меня не работает при использовании asyncio.gather. Как собрать результаты нескольких вызовов get_result?

Код: Выделить всё

In [162]: import asyncio

In [163]: from typing import Awaitable

In [164]: async def get_result(awaitable: Awaitable) -> str:
...:      try:
...:          result = await awaitable
...:      except Exception as e:
...:          print("oops!", e)
...:          return "no result"
...:      else:
...:          return result
...:

In [165]: loop = asyncio.new_event_loop()

In [166]: f = asyncio.Future(loop=loop)

In [167]: loop.call_later(20, f.set_result, "final result")
...:
...: loop.run_until_complete(asyncio.gather(get_result(f), get_result(f), get_result(f)))
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[167], line 3
1 loop.call_later(20, f.set_result, "final result")
----> 3 loop.run_until_complete(asyncio.gather(get_result(f), get_result(f), get_result(f)))

File /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/tasks.py:884, in gather(return_exceptions, *coros_or_futures)
882 for arg in coros_or_futures:
883     if arg not in arg_to_fut:
--> 884         fut = ensure_future(arg, loop=loop)
885         if loop is None:
886             loop = futures._get_loop(fut)

File /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/tasks.py:746, in ensure_future(coro_or_future, loop)
742         raise TypeError('An asyncio.Future, a coroutine or an awaitable '
743                         'is required')
745 if loop is None:
--> 746     loop = events.get_event_loop()
747 try:
748     return loop.create_task(coro_or_future)

File /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/events.py:716, in BaseDefaultEventLoopPolicy.get_event_loop(self)
713     self.set_event_loop(self.new_event_loop())
715 if self._local._loop is None:
--> 716     raise RuntimeError('There is no current event loop in thread %r.'
717                        % threading.current_thread().name)
719 return self._local._loop

RuntimeError: There is no current event loop in thread 'MainThread'.

Я также пытался использовать await asyncio.gather, но получил еще одну ошибку, как показано ниже:

Код: Выделить всё

In [168]: loop = asyncio.new_event_loop()

In [169]: f = asyncio.Future(loop=loop)

In [170]: loop.call_later(10, f.set_result, "final result")
...:
...: await asyncio.gather(get_result(f))
oops! Task  got Future  attached to a different loop
Out[170]: ['no result']

Похоже, что asyncio.gather() создает задачу, прикрепленную к новому циклу, а не к моему созданному циклу. Можно ли использовать сбор, используя созданный мной цикл?
Видео инструктора создано 5 лет назад, и я предполагаю, что asyncio изменился до сих пор.

Подробнее здесь: https://stackoverflow.com/questions/798 ... -exception
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»