asyncio.run失败时loop.run_until_complete作品(asyncio.ru

2019-09-29 04:58发布

此代码失败:

import asyncio
from motor import motor_asyncio


_client = motor_asyncio.AsyncIOMotorClient()
_db = _client.db

users = _db.users


async def main():
    await users.create_index(
        'login',
        unique=True
    )


if __name__ == '__main__':
    #loop = asyncio.get_event_loop()
    #loop.run_until_complete(main())
    asyncio.run(main())

与此错误:

Traceback (most recent call last):
  File "/home/sanyash/myrepos/TKP/db.py", line 21, in <module>
    asyncio.run(main())
  File "/usr/local/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/usr/local/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "/home/sanyash/myrepos/TKP/db.py", line 14, in main
    unique=True
RuntimeError: Task <Task pending coro=<main() running at /home/sanyash/myrepos/TKP/db.py:14> cb=[_run_until_complete_cb() at /usr/local/lib/python3.7/asyncio/base_events.py:158]> got Future <Future pending cb=[run_on_executor.<locals>._call_check_cancel() at /usr/local/lib/python3.7/motor/frameworks/asyncio/__init__.py:80]> attached to a different loop

当我取消两行loop和评论asyncio.run它工作得很好。 什么事? 我想asyncio.run是这两条线的快捷方式。

问题是东西在motor_asyncio实现,因为当我改变main以简单的return 42asyncio.run工作也很好。

Answer 1:

什么事? 我想asyncio.run是这两条线的快捷方式。

不,它更多。 特别是它创建和设置一个新的事件循环。 这就是为什么你会得到错误: AsyncIOMotorClient()创建默认的事件循环的一些异步的东西,而是创造了另一个循环asyncio.run尝试使用它。

如果您想保留asyncio.run你应该将初始化里面的东西main()

# ...

_client = None
_db = None
users = None


async def main():
    global _client, _db, users
    _client = motor_asyncio.AsyncIOMotorClient()
    _db = _client.db
    users = _db.users

    # ...

这是一般的好主意,当事件循环已经设置并运行的,而不是做在模块级的东西开始的事情。



文章来源: asyncio.run fails when loop.run_until_complete works