【问题标题】:How to make output ipywidget capture only stdout?如何使输出 ipywidget 仅捕获标准输出?
【发布时间】:2020-02-14 23:34:26
【问题描述】:

我希望从一个函数中捕获 stdout 输出,这样当第一次调用该函数时,它的输出将正常显示在 iPython notebook 中,但是当它第二次调用时,它的输出将重写之前的输出. (这样之前的输出会被清除,新的输出会显示在同一个地方)

我已经使用输出 ipywidget 实现了我想要的,尽管它也捕获并清除了 stderr。不幸的是,这是不可接受的,因为我需要在程序完成时显示 stderr 输出。

这是我目前拥有的代码的最小(非)工作示例:

import sys
from ipywidgets import widgets
from IPython.display import display, clear_output

# This function is in some library and cannot be changed
def black_box(iter):
    print('Some output to stdout {}.'.format(iter)) #This is supposed to be cleared on each function call
    sys.stderr.write('Some output to stderr {}.'.format(iter)) #This is NOT supposed to be cleared on each function call

print('Some other output that is not supposed to be cleared.')

output = widgets.Output()
display(output)

with output: # I need this to capture only stdout, not stderr ...
    black_box(1)

print('Some other output that is not supposed to be cleared.')

with output:
    clear_output() # ... so that this line clears only stdout, not stderr
    black_box(2)

输出如下:

Some other output that is not supposed to be cleared.
Some output to stdout 2.
Some output to stderr 2.
Some other output that is not supposed to be cleared.

我希望输出的样子:

Some other output that is not supposed to be cleared.
Some output to stdout 2.
Some output to stderr 1.
Some output to stderr 2.
Some other output that is not supposed to be cleared.

如您所见,stderr 输出也在第二个函数调用中被捕获和清除。有谁知道解决这个问题的任何方法?谢谢。

【问题讨论】:

    标签: python-3.x jupyter-lab ipywidgets


    【解决方案1】:

    你试过ipythonmagics吗?它有--no-stderr--no-stdout 等选项

    【讨论】:

    • 感谢您的宝贵时间!不幸的是,您的解决方案会影响整个单元格的输出。我需要的是只捕获函数的输出,这样就行不通了。 ipywidgets 的输出非常适合,不幸的是,根据其中一位开发人员的说法,当前的实现不可能只清除 stdout 或 stderr。
    【解决方案2】:

    我不清楚您使用的是什么小部件以及它如何与功能交互。我也不明白为什么其他命令必须在同一个单元格上,因为我知道小部件会吐出输出。

    不管怎样,这就是我刚刚学到的试图回答你的问题。

    鉴于此代码(在 Colab 中工作)

    import sys
    from ipywidgets import widgets
    from IPython.display import display, clear_output
    
    w= widgets.ToggleButtons(options=['1','2','3'])
    output = widgets.Output()
    display(w,output)
    #--------------------
    # This function is in some library and cannot be changed
    def black_box(iter):
      with output:
        output.clear_output()
        print('Inside STD Some output to stdout {}.'.format(iter)) #This is supposed to be cleared on each function call
        sys.stderr.write('INSIDE ERR Some output to stderr {}.'.format(iter)) #This is NOT supposed to be cleared on each function call
    
      print('Outside STD Some output to stdout {}.'.format(iter)) #This is supposed to be cleared on each function call
      sys.stderr.write('OUTSIDE ERR Some output to stderr {}.'.format(iter)) #This is NOT supposed to be cleared on each function call
    #--------------------
    
    # Add a tracker for changes on widget
    w.observe(black_box, names = 'value')
    
    
    print('As usual...')
    

    运行单元后我得到

    按下一个按钮后,我得到

    按下另一个按钮后,我得到

    (一些)结论:

    • OUTSIDE ERR 输出始终保持不变,即不受 clear_output() 或 with 影响

    • STD 总是受到clear_output() 的影响,无论内部/外部with

    • with 内的 ERR 受 the clear_output() 影响

    知道我认为您有解决问题的工具。正如许多人所说,如果您在问题中使用“功能齐全”的代码,则更容易为您提供“功能齐全的答案”。

    注意:我刚刚了解了withoutput,感谢这篇很棒的文章https://medium.com/@socjon/ipywidgets-handler-quick-overview-c9b9246345d9 那里的许多其他文章只是在某种程度上克隆了文档,这篇文章显然没有这样做。

    还请注意,您可以将输出放置在任何您想要的位置,甚至可以将其框起来。

    output = widgets.Output(layout={'border': '1px solid yellow'})
    output2 = widgets.Output(layout={'border': '1px solid pink'})
    display(w,output)
    ....
    
    print('As usual...')
    display(output2)
    

    生产

    更多信息https://ipywidgets.readthedocs.io/en/stable/examples/Output%20Widget.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-29
      • 2021-05-21
      • 1970-01-01
      • 2011-04-17
      • 1970-01-01
      • 2017-07-09
      相关资源
      最近更新 更多