asyncio.run 在 loop.run_until_complete 有效时失败
asyncio.run fails when loop.run_until_complete works
此代码失败:
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 42
时,asyncio.run
也能正常工作。
What the matter? I thought asyncio.run
is a shortcut for this two
lines.
不,它做得更多。特别是它 creates and sets 一个新的事件循环。这就是你得到错误的原因:AsyncIOMotorClient()
为默认事件循环创建了一些异步内容,但是 asyncio.run
创建的另一个循环试图使用它。
如果你想保留 asyncio.run
你应该把 init 东西移到 main()
:
# ...
_client = None
_db = None
users = None
async def main():
global _client, _db, users
_client = motor_asyncio.AsyncIOMotorClient()
_db = _client.db
users = _db.users
# ...
一般来说,在事件循环已经设置好时开始做事是个好主意,运行而不是在模块级别做事。
此代码失败:
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 42
时,asyncio.run
也能正常工作。
What the matter? I thought
asyncio.run
is a shortcut for this two lines.
不,它做得更多。特别是它 creates and sets 一个新的事件循环。这就是你得到错误的原因:AsyncIOMotorClient()
为默认事件循环创建了一些异步内容,但是 asyncio.run
创建的另一个循环试图使用它。
如果你想保留 asyncio.run
你应该把 init 东西移到 main()
:
# ...
_client = None
_db = None
users = None
async def main():
global _client, _db, users
_client = motor_asyncio.AsyncIOMotorClient()
_db = _client.db
users = _db.users
# ...
一般来说,在事件循环已经设置好时开始做事是个好主意,运行而不是在模块级别做事。