当loop.run_until_complete工作时asyncio.run失败

时间:2019-03-29 21:40:47

标签: python python-asyncio python-3.7 motor-asyncio

此代码失败:

class ReusableHeaderView: UICollectionReusableView {
    let imageView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setupUI()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setupUI()
    }

    private func setupUI() {
        self.addSubview(imageView)

        // Instead of settings imageView.frame, add following to use autolayout constraints
        self.imageView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            imageView.topAnchor.constraint(equalTo: self.topAnchor),
            imageView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -10.0),
            imageView.widthAnchor.constraint(equalToConstant: 20.0),
            imageView.heightAnchor.constraint(equalToConstant: 20.0)
        ])
    }

}

出现此错误:

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也很好用。

1 个答案:

答案 0 :(得分:3)

  

怎么回事?我以为asyncio.run是这两个的捷径   行。

不,它还有更多功能。特别是creates and sets一个新的事件循环。这就是为什么会出现错误的原因: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

    # ...

通常最好在事件循环已设置并正在运行时开始而不是在模块级别执行操作。