程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了线程化的IPython Notebook的每单元输出大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决线程化的IPython Notebook的每单元输出?

开发过程中遇到线程化的IPython Notebook的每单元输出的问题如何解决?下面主要结合日常开发的经验,给出你关于线程化的IPython Notebook的每单元输出的解决方法建议,希望对你解决线程化的IPython Notebook的每单元输出有所启发或帮助;

更新:

不,print语句的重要部分根本没有固定连接。print只需写入sys.stdout,它可以是任何带有writeflush方法的对象。IPython已经完全替换了此对象,以便首先将stdout传递到笔记本(请参见下文)。

否-只需覆盖sys.stdout即可,而不是自己打印(请参见上面,下面和其他地方)。这里没有Python 3的优势。

当然- IPython笔记本本身。它使用消息ID和元数据来确定stdout消息的来源,然后确定这些消息应在何处结束。下面,在我对显然没有人提出的问题的原始回答中,我展示了一个示例,该示例同时绘制来自多个线程正在同时运行的单元的输出。

为了获得所需的刷新行为,您可能需要做两件事:

  1. 将sys.stdout替换为您自己的对象,该对象使用IPython显示协议发送带有您自己的线程识别元数据(例如threading.current_thread().IDent)的消息。这应该在上下文管理器中完成(如下所示),因此它只会影响您实际想要的打印语句。
  2. 编写一个IPython Js插件来处理您的stdout消息的新格式,以便它们不会立即绘制,而是存储在数组中,等待绘制。

原始答案(错误,但相关的问题):

它依赖于一些恶作剧和私有API,但这在当前的IPython中是完全可能的(可能不会永远存在)。

这是一个示例笔记本:http ://nbviewer.ipython.org/4563193

为此,您首先需要了解IPython如何将标准输出到笔记本。这是通过用OutStream对象替换sys.stdout来完成的。这将缓冲数据,然后在调用时通过zeromq发送数据,sys.stdout.flush最终将其存储在浏览器中。

现在,如何将输出发送到特定的单元格。

IPython消息协议 使用“父”标头来标识哪个请求产生了哪个答复。每次您要求IPython运行一些代码时,它都会设置各种对象的父标头(包括sys.stdout),以便它们的副作用消息与导致它们的消息相关联。在线程中运行代码时,这意味着当前的parent_header只是最新的execute_request,而不是启动任何给定线程的原始parent_header。

虑到这一点,这是一个上下文管理器,可将stdout的父标头临时设置为特定值:

import sys
from contextlib import contextmanager


stdout_lock = threading.Lock()

@contextmanager
def set_stdout_parent(parent):
    """a context manager for setTing a particular parent for sys.stdout

    the parent determines the desTination cell of output
    """
    save_parent = sys.stdout.parent_header

    # we need a lock, so that other threads don't snatch control
    # while we have set a temporary parent
    with stdout_lock:
        sys.stdout.parent_header = parent
        try:
            yIEld
        finally:
            # the flush is important, because that's when the parent_header actually has its effect
            sys.stdout.flush()
            sys.stdout.parent_header = save_parent

这是一个线程,它在线程启动时记录父对象,并在每次执行print语句时都应用该父对象,因此它的行为就像仍在原始单元格中一样:

import threading

class counterThread(threading.Thread):
    def run(self):
        # record the parent when the thread starts
        thread_parent = sys.stdout.parent_header
        for i in range(3):
            time.sleep(2)
            # then ensure that the parent is the same as when the thread started
            # every time we print
            with set_stdout_parent(thread_parent):
                print i

最后,一个笔记本将所有内容捆绑在一起,并带有时间戳,显示实际并发打印到多个单元格:

http://nbviewer.ipython.org/4563193/

解决方法

我不想提出这个问题,因为对于一个相当出色的工具来说,这似乎是一个完全不合理的功能要求。但是,如果有任何读者对体系结构熟悉,我很想知道潜在的扩展是否可行。

我最近写了一个笔记本,里面有一些简单的线程代码,只是想看看我运行它时会发生什么。笔记本代码(tl;
dr启动了多个在睡眠循环中打印的并行线程)可在https://gist.github.com/4562840上获得。

通过在代码运行时按SHIFT-RETURN几次,您可以观察到内核的任何输出都出现在当前单元格的输出区域中,而不是运行代码的单元格的输出区域中。

我想知道是否有可能,如果某个单元格中的线程处于活动状态,则显示“刷新”按钮以允许异步更新输出区域。理想情况下,如果在所有线程结束后(在最终更新之后)单击刷新按钮,该按钮将消失。

但是,这将取决于能否识别和拦截每个线程的打印输出并将其定向到特定单元输出的缓冲区。所以,有两个问题。

  1. 我是否认为Python 2的print语句很难用,这意味着标准的解释器无法实现此增强功能,我是否正确?

  2. 鉴于可以在IPython内核中的另一层偷偷进入print()堆栈,Python 3的前景会更好吗?特别是对于那些不遵循Python链接到达此处的人,

  3. [没有人期望西班牙宗教裁判所]更笼统地说,您能否指出将多个流传递到页面中的示例(与语言无关)?是否存在用于构建和修改DOM以解决此问题的最佳实践?

大佬总结

以上是大佬教程为你收集整理的线程化的IPython Notebook的每单元输出全部内容,希望文章能够帮你解决线程化的IPython Notebook的每单元输出所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。