如何在Jupyter笔记本中运行Python异步代码? [英] How do I run Python asyncio code in a Jupyter notebook?

查看:501
本文介绍了如何在Jupyter笔记本中运行Python异步代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些异步代码,可以在Python解释器(CPython 3.6.2)中正常运行.我现在想在带有IPython内核的Jupyter笔记本中运行此程序.

I have some asyncio code which runs fine in the Python interpreter (CPython 3.6.2). I would now like to run this inside a Jupyter notebook with an IPython kernel.

我可以用它运行

import asyncio
asyncio.get_event_loop().run_forever()

虽然这似乎可行,但它似乎也挡住了笔记本电脑,并且在笔记本电脑上玩起来并不好.

and while that seems to work it also seems to block the notebook and doesn't seem to play nice with the notebook.

我的理解是Jupyter在引擎盖下使用了Tornado,所以我尝试安装Tornado事件按照Tornado文档中的建议进行循环:

My understanding is that Jupyter uses Tornado under the hood so I tried to install a Tornado event loop as recommended in the Tornado docs:

from tornado.platform.asyncio import AsyncIOMainLoop
AsyncIOMainLoop().install()

但是会出现以下错误:

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-1-1139449343fc> in <module>()
      1 from tornado.platform.asyncio import AsyncIOMainLoop
----> 2 AsyncIOMainLoop().install()

~\AppData\Local\Continuum\Anaconda3\envs\numismatic\lib\site- packages\tornado\ioloop.py in install(self)
    179         `IOLoop` (e.g.,     :class:`tornado.httpclient.AsyncHTTPClient`).
    180         """
--> 181         assert not IOLoop.initialized()
    182         IOLoop._instance = self
    183 

AssertionError: 

最后,我找到了以下页面: http://ipywidgets.readthedocs .io/en/stable/examples/Widget%20Asynchronous.html

Finally I found the following page: http://ipywidgets.readthedocs.io/en/stable/examples/Widget%20Asynchronous.html

所以我添加了一个带有以下代码的单元格:

so I added a cell with the following code:

import asyncio
from ipykernel.eventloops import register_integration

@register_integration('asyncio')
def loop_asyncio(kernel):
    '''Start a kernel with asyncio event loop support.'''
    loop = asyncio.get_event_loop()

    def kernel_handler():
        loop.call_soon(kernel.do_one_iteration)
        loop.call_later(kernel._poll_interval, kernel_handler)

    loop.call_soon(kernel_handler)
    try:
        if not loop.is_running():
            loop.run_forever()
    finally:
        loop.run_until_complete(loop.shutdown_asyncgens())
        loop.close()

然后在下一个单元格中运行:

and in the next cell I ran:

%gui asyncio

那行得通,但我真的不明白为什么以及如何运行.有人可以向我解释一下吗?

That worked but I don't really understand why and how it works. Can someone please explain that to me?

推荐答案

编辑二月21st,问题:已解决

最新版本的Jupyter Notebook不再是问题. Jupyter Notebook的作者在此处详细介绍了这种情况.

This is no longer an issue on the latest version of Jupyter Notebook. Authors of Jupyter Notebook detailed the case here.

下面的答案是被操作员标记为正确的原始回复.

Answer below was the original response that was marked correct by the op.

这是在很早以前发布的,但是如果其他人正在寻找有关在Jupyter Notebook中运行异步代码的问题的解释和解决方案,请联系我们.

This was posted quite a bit ago, but in case other people are looking for an explanation and solution to the problem of running asynchronous code inside Jupyter Notebook;

Jupyter的Tornado 5.0在添加了自己的asyncio事件循环之后,更新了砖化的asyncio功能:

Jupyter's Tornado 5.0 update bricked asyncio functionalities after the addition of its own asyncio event loop:

的终端输出

因此,对于要在Jupyter Notebook上运行的任何异步功能,您不能调用run_until_complete(),因为将从asyncio.get_event_loop()接收到的循环将处于活动状态.

Thus, for any asyncio functionality to run on Jupyter Notebook you cannot invoke a run_until_complete(), since the loop you will receive from asyncio.get_event_loop() will be active.

相反,您必须将任务添加到当前循环:

Instead, you must add task to the current loop:

import asyncio
loop = asyncio.get_event_loop()
loop.create_task(some_async_function())

在Jupyter Notebook上运行的简单示例:

A simple example running on Jupyter Notebook:

这篇关于如何在Jupyter笔记本中运行Python异步代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆