我想在ipython笔记本上做一些ROOT文件的操作(ROOT这里是CERN的ROOT数据分析程序和python界面)。 ROOT的烦人特性之一是它经常直接向stdout发送输出,而不是像字符串那样返回这样的输出。为了让这个输出出现在IPython的笔记本于是,我写了一个小cell_magic
说:不能访问ipython中的笔记本变量cell_magic
- 告诉ROOT到标准输出重定向到一个文件
- 运行在电池python命令
- 匝关闭ROOT的输出重定向
- 读取文件和打印内容
这里是我的小细胞魔码
import tempfile
import ROOT
from IPython.core.magic import register_cell_magic
@register_cell_magic
def rootprint(line, cell):
"""Capture Root stdout output and print in ipython notebook."""
with tempfile.NamedTemporaryFile() as tmpFile:
ROOT.gSystem.RedirectOutput(tmpFile.name, "w")
exec cell
ROOT.gROOT.ProcessLine("gSystem->RedirectOutput(0);")
print tmpFile.read()
如果我把这段代码放到一个ipython笔记本单元中并执行它,那么这个工作很好。例如,
In [53]: f = ROOT.TFile('myRootFile.root') # Load the Root file
In [54]: %%rootprint
f.ls() # Show the contents of the ROOT file
... f.ls() output appears here - yay! ...
通常的f.ls()
输出变为标准输出并没有出现作为细胞的结果。但有了这种细胞魔法,输出确实出现在细胞结果中!这很棒!
但是,如果我把细胞魔法代码放到一个模块中,那么它不起作用。例如,我把上面的代码放到了ipythonRoot.py
,并在笔记本上做了import ipythonRoot.py
。当我尝试运行上面的%%rootprint
单元格时,出现错误,说明f
未定义。我试图将exec
行更改为exec cell in globals()
,但这并没有帮助。
有没有办法做到这一点?另外,是否有更好的方法来编写cell_magic
函数(例如,我应该返回输出而不是打印它)?预先感谢任何帮助!
感谢您的好提示! Root的一个问题是它自己处理stdout/err,所以我不认为有办法让它重定向到一个文件。 – Adam 2013-02-23 14:39:43