使用管道将打印到STDERR的东西捕获到Jupyter的Python变量中

Yar*_*tov 10 python ipython jupyter

当我在jupyter笔记本中运行命令时,我正在尝试捕获打印到STDERR的内容.特别是,我正在使用TensorFlow,它fprintf来自C部分,通常打印在控制台上,但我想保存到Python变量中.

我一直在使用来自IPython codebase的 FDRedirector,它设置os.pipe为将输出捕获到Python字符串中.

但是,这段代码的问题在于它会挂起内核以获得足够大的输出.我怀疑它会挂起超过65k的输出,因为Linux上的管道缓冲区大小并gdb显示挂起正在发生write.有没有人有一个适用于更大产出的解决方案?

作为我现在正在做的事情的一个例子,使用FDRedirector

STDERR = 2
redirect = FDRedirector(STDERR)
import tensorflow as tf
sess = tf.Session("")
node = tf.Print(tf.constant(1), [tf.constant(1)], "longstringlongstring")
def print_to_stderr():
    sess.run(node)   # this prints to stderr
redirect.start();
print_to_stderr()
captured_stderr = redirect.stop()
Run Code Online (Sandbox Code Playgroud)

最后,"captured_stderr"包含打印到stderr的所有内容,包括longstringlongstring.如果你做得longstring更长(> 100k),这将冻结.

Iva*_*van 3

您可以尝试将输出传输到临时文件 - 这样就没有缓冲区限制:

STDERR=2
STDOUT=1
import os
import sys
import tempfile

class captured:
    def __init__(self, fd=STDERR):
        self.fd = fd
        self.prevfd = None

    def __enter__(self):
        t = tempfile.NamedTemporaryFile()
        print 'Piping your output to ' + t.name
        self.prevfd = os.dup(self.fd)
        os.dup2(t.fileno(), self.fd)
        return t

    def __exit__(self, exc_type, exc_value, traceback):
        os.dup2(self.prevfd, self.fd)

with captured(fd=STDOUT) as tmp:
    os.system('cat 1mbfile.txt');

print "Captured:", open(tmp.name).read()    
Run Code Online (Sandbox Code Playgroud)

请告诉我这是否适合您的目的。不幸的是我没有安装TF。

Jupyter 本身幸存下来,向单元输出 1Mb :)