用于阻止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第三方库


热门话题
hibernate java JPA使用限制api调用sql函数   java使用哈希代码确定对象等价性   java通过蓝牙在安卓应用程序和pc应用程序之间发送敏感数据   mysql查询在java上不提供小数,但在数据库上提供小数   java链接的JAR在IntelliJ中运行良好,但在命令行中却不行   mkstemp的java等价物   java SINGLE_INTERVAL_SELECTION未按预期工作   使用Java流的lambda并行循环?   java如何增加按键上的数字值?   java karaf单个依赖项错误   具有共享主键的java JPA单向@OneToOne关系始终会触发辅助查询,即使fetchType是急切的   java为什么选择。select()总是返回0   java无法确定NullPointerException中哪个变量为null   字符串Java谜题的原因是什么?