如何解决iPython,保存代码单元的输出并在执行期间仍然正常显示输出
所以,这个问题的通常答案是使用细胞魔法“%%caputre cap”, 问题是它会抑制正常输出并显示它,您必须在执行单元格后运行“cap.show()”。 当运行一个需要很长时间的单元时,比如训练一个神经网络,这个功能会让人头疼。 如何运行我的代码单元并像往常一样获得实时输出,然后才能将其保存到 .txt 文件中?
解决方法
这不是特定于 IPython/Jupyter 的,但这是我为类似目的编写的上下文管理器:
import sys
class capture_stdout:
"""
Context manager similar to `contextlib.redirect_stdout`,but
different in that it:
- temporarily writes stdout to other streams *in addition to*
rather than *instead of* `sys.stdout`
- accepts any number of streams and sends stdout to each
- can optionally keep streams open after exiting context by
passing `closing=False`
Parameters
----------
*streams : *`io.IOBase`
stream(s) to receive data sent to `sys.stdout`
closing : `bool`,optional
if [default: `True`],close streams upon exiting the context
block.
"""
def __init__(self,*streams,closing=True):
self.streams = streams
self.closing = closing
self.sys_stdout_write = sys.stdout.write
def __enter__(self):
sys.stdout.write = self._write
if len(self.streams) == 1:
return self.streams[0]
return self.streams
def __exit__(self,exc_type,exc_value,traceback):
sys.stdout.write = self.sys_stdout_write
if self.closing:
for s in self.streams:
s.close()
def _write(self,data):
for s in self.streams:
s.write(data)
self.sys_stdout_write(data)
sys.stdout.flush()
您可以传递任意数量的流,并且它会实时写入所有和常规sys.stdout
。因此,例如,如果您想显示实时输出,捕获它以供稍后在代码中使用,并将其记录到文件中,您可以这样做:
from io import StringIO
with capture_stdout(StringIO(),open('logfile.txt','w')) as (mem_stream,file_stream):
print('some really long output')
# etc...
stdout = mem_stream.getvalue()
print(f"in str: {stdout}")
with open('logfile.txt','r') as f:
print(f"in file: {f.read()}")
some really long output
in str: some really long output
in file: some really long output
变成同样工作的细胞魔法也不应该太难。 Here 是关于定义自定义魔法的 IPython
文档部分,如果您想试一试的话。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。