用于阻止jupyter笔记本中单元执行的上下文管理器

ipython-blocking的Python项目详细描述


ipython_阻塞

Binder

ipython_blocking是一个上下文管理器,用于捕获jupyter笔记本中的单元格执行消息,以及方便使用的魔术命令%block%blockrun。阻止笔记本执行的主要用例是等待用户与ipywidgets交互,然后引用这些小部件中输入的值。

安装

ipython_blockingPyPI上,使用pip安装。

pipinstallipython_blocking

使用量

试用活页夹中的演示笔记本,查看ipython_blocking的实际效果。使用ipython_blocking最常见的方法是使用%blockrun魔法并运行一个带有“cell->;run all”的笔记本。%blockrun button停止来自初始“cell->;run all”的单元格执行消息,并将“cell->;run all below”处理程序附加到按钮,以便在用户填写其他小部件值后,笔记本可以以线性方式运行,而无需回调函数。

### cell #1importipywidgetsaswidgetsimportipython_blocking# enables %block and %blockrun magictext=widgets.Text()dropdown=widgets.Dropdown(options=['','foo','bar','baz'])button=widgets.Button(description='Run')box=widgets.VBox(children=[text,dropdown,button])box### cell #2%blockrunbutton### cell #3 -- doesn't execute until the 'Run' button is pressed### This gives the user a chance to interact with the Text and Dropdown widgetsprint(text.value)print(dropdown.value)

(下拉菜单不在此.gif中显示,因为它在Windows屏幕捕获中被视为“单独的窗口”,抱歉!)

捕获执行

ipython_blocking“阻塞”单元执行的方法是创建一个上下文管理器,该管理器更改IPython.shell.kernel['execute_request']处理程序的行为。当您在jupyter笔记本中执行一个单元格时,它会用该代码向内核发送一条execute_request通信消息。

CaptureExecution管理器正在“阻塞”时,它将这些消息存储在列表中,而不是实际执行它们。当上下文管理器退出时,它将处理程序重置为其原来的行为,然后重放存储的消息或丢弃它们。

importipython_blockingctx=ipython_blocking.CaptureExecution(replay=True)withctx:whileTrue:ifbreak_function():breakctx.step()# handles all other messages that aren't 'execute_request' including widget value changes

%块

导入ipython_blocking时启用%block魔术。它接受一个函数或小部件对象并创建CaptureExecution管理器来阻塞,直到该函数返回true或小部件值更改为止。

# cell 1importipywidgetsaswidgetsimportipython_blockingdd=widgets.Dropdown(options=['','foo','bar',baz'])dd# cell 2%blockdd# cell 3# Won't actually be executed until the user chooses an option in the dd widgetprint(dd.value)

%块运行

%blockrun魔术与%block相似,但它只接受ipywidgets.Button目标,并将“cell->;run all below”处理程序附加到按钮。如果您希望笔记本的应用程序逻辑运行不止一次(和/或不想重新初始化小部件,因为用户可能只更改许多选项中的一个),那么%blockrun是更好的魔法。

当笔记本首次呈现时,使目标Button不可访问通常很方便,然后在其他小部件上添加.observe处理程序,这些小部件可以使Button在发生某些输入验证后可单击。

# cell 1importipywidgetsaswidgetsimportipython_blockingtext=widgets.Text()dd=widgets.Dropdown(options=['','foo','bar','baz'])button=widgets.Button(description='Run',disabled=True)defvalidation(ev):"make button clickable if user has put in more than 5 characters and chosen a dropdown option"iflen(text.value)>5anddd.value:button.disabled=Falseelse:button.disabled=Truetext.observe(validation)dd.observe(validation)box=widgets.VBox(children=[text,dd,button])box# cell 2%blockrunbutton# cell 3print(text.value)print(dd.value)

替代方案

用户与小部件交互后获取小部件值的其他方法是使用event callbacks构造笔记本或编写代码asynchronously

我相信以线性和同步方式编写jupyter笔记本的应用程序逻辑有很大的好处,在笔记本全局范围内有尽可能多的变量。这些好处包括:

  • 更好地反省和理解工作流程(不要用globalprint语句乱扔代码)
  • 出错时进行更直接的调试
  • 更容易将代码分解成小块/单元格

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
Java Date作为MyBatis中Oracle SELECT查询的参数[not get Response]   来自两个独立线程的并行java访问队列   如果数据已经存在,java Android Studio SQLite不会将数据插入数据库   mysql java spring项目仅在第一次运行时显示错误,再次运行后运行正常。为什么呢?   java SQL错误:1364,SQLState:HY000字段“rating_id”没有默认值/保存具有onetoone关系的子实体时   Tomcat中无cookie的java支持会话#重复   JAVAlang.RuntimeException:Android Studio   java CheckboxMultipleChice存储在SQL中   Kafka Java SimpleConsumer奇怪的编码   使用Hibernate保存servlet中处理的数据时遇到java错误   JavaSpring在运行时添加数据源   java使用一个类中另一个类的方法   java空值随Spring Rest资源更新   java Spring引导:为什么要使用OncePerRequestFilter?   java Android异步任务重用   java JTextField未按预期填充列?