代码之家  ›  专栏  ›  技术社区  ›  python_user

RuntimeError:事件循环在asyncpraw python中关闭

  •  0
  • python_user  · 技术社区  · 3 年前

    我正在尝试使用 asyncpraw 图书馆,但我得到 RuntimeError: Event loop is closed .

    这是我的代码和回溯。

    代码

    import asyncio
    import asyncpraw
    
    async def main():
        reddit = asyncpraw.Reddit('praw_ini_name')
        print('User is', await reddit.user.me())
        await reddit.close()
    
    asyncio.run(main())
    

    追溯

    User is python_user
    Exception ignored in: <function _ProactorBasePipeTransport.__del__ at 0x0000021D2898C1F0>
    Traceback (most recent call last):
      File "C:\Program Files\Python39\lib\asyncio\proactor_events.py", line 116, in __del__
        self.close()
      File "C:\Program Files\Python39\lib\asyncio\proactor_events.py", line 108, in close
        self._loop.call_soon(self._call_connection_lost, None)
      File "C:\Program Files\Python39\lib\asyncio\base_events.py", line 746, in call_soon
        self._check_closed()
      File "C:\Program Files\Python39\lib\asyncio\base_events.py", line 510, in _check_closed
        raise RuntimeError('Event loop is closed')
    RuntimeError: Event loop is closed
    

    然而,如果我这样启动事件循环,就不会发生这种情况(没有例外)

    import asyncio
    import asyncpraw
    
    async def main():
        reddit = asyncpraw.Reddit('praw_ini_name')
        print('User is', await reddit.user.me())
        await reddit.close()
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    

    我假设在较新的python版本中,启动事件循环的首选方式是我在第一个代码片段中展示的方式,那么为什么这不起作用呢?即使它打印了输出,为什么我的代码会抛出异常?

    我使用的是Python 3.9.2 asyncpraw 7.2.0.

    我见过 Asyncio Event Loop is Closed , Python3.x RuntimeError: Event loop is closed Aiohttp, Asyncio: RuntimeError: Event loop is closed 我相信他们不是骗子。我的问题是,为什么它只适用于一种,而不适用于另一种。

    如果我不使用 reddit.close() 我得到以下信息

    User is python_user
    Unclosed client session
    client_session: <aiohttp.client.ClientSession object at 0x0000025BAAAEF8B0>
    Unclosed connector
    connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x0000025BAAAF1640>, 174448.968)]']
    connector: <aiohttp.connector.TCPConnector object at 0x0000025BAAAEFA90>
    

    非常感谢。

    0 回复  |  直到 3 年前
        1
  •  2
  •   MisterMiyagi    3 年前

    asyncio.run explicity在完成时关闭循环。

    asyncio.run(coro, *, debug=False)

    [...]
    此函数始终创建一个新的事件循环,并在结束时将其关闭。

    这意味着事件循环是 可用于清理一次 main 完成。相反,必须通过以下方式果断地进行清理 async generators ,或同步。

    手动管理循环而不调用时 loop.close() ,循环仍然可用于安排清理回调。请注意,这并不一定意味着清理工作实际上是 运行 除非循环被明确地恢复。


    具体的问题是 known issue with aiohttp 3.x .