无法访问ipython cell_magic中的笔记本变量
我正在尝试对ipython笔记本中的根文件进行一些操作(这里的ROOT是CERN的根数据分析程序,带有python接口)。ROOT的一个恼人的特性是它经常直接将输出发送到stdout,而不是以字符串的形式返回这样的输出。为了让这个输出结果出现在ipython笔记本上,我写了一点无法访问ipython cell_magic中的笔记本变量,ipython,ipython-notebook,Ipython,Ipython Notebook,我正在尝试对ipython笔记本中的根文件进行一些操作(这里的ROOT是CERN的根数据分析程序,带有python接口)。ROOT的一个恼人的特性是它经常直接将输出发送到stdout,而不是以字符串的形式返回这样的输出。为了让这个输出结果出现在ipython笔记本上,我写了一点cell_magic: 告诉ROOT用户将标准输出重定向到文件 在单元格中运行python命令 关闭根目录的输出重定向 读取文件并打印内容 这是我的小手机密码 import tempfile import ROOT f
cell_magic
:
- 告诉ROOT用户将标准输出重定向到文件
- 在单元格中运行python命令
- 关闭根目录的输出重定向
- 读取文件并打印内容
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
并在笔记本中导入ipythonRoot.py。当我尝试运行上面的%%rootprint
单元格时,我得到一个错误,表示未定义f
。我尝试将globals()中的exec
行更改为exec单元格,但没有效果
有办法做到这一点吗?另外,是否有更好的方法编写cell\u magic
函数(例如,我是否应该返回输出而不是打印输出)?提前感谢您的帮助 如果我理解正确,magic/alias/user名称空间是分开的。执行“导入”不会干扰magic/alias命名空间。
这就是为什么会有%load\u ext魔法的原因,但是您必须定义您的入口点。[使用R magic的示例]。()
此外,我还建议您在不使用临时文件的情况下捕获stdout/err
一旦成功,您还可以将扩展添加到,因此我通过查看IPython代码,特别是IPython/core/magics/execution.py,找到了一些很好的提示。这是我的新模块
import tempfile
import ROOT
from IPython.core.magic import (Magics, magics_class, cell_magic)
@magics_class
class RootMagics(Magics):
"""Magics related to Root.
%%rootprint - Capture Root stdout output and show in result cell
"""
def __init__(self, shell):
super(RootMagics, self).__init__(shell)
@cell_magic
def rootprint(self, line, cell):
"""Capture Root stdout output and print in ipython notebook."""
with tempfile.NamedTemporaryFile() as tmpFile:
ROOT.gSystem.RedirectOutput(tmpFile.name, "w")
ns = {}
exec cell in self.shell.user_ns, ns
ROOT.gROOT.ProcessLine("gSystem->RedirectOutput(0);")
print tmpFile.read()
# Register
ip = get_ipython()
ip.register_magics(RootMagics)
请注意使用了Magics
类和shell
属性,其中包含笔记本的名称空间。这可以定期导入,而且效果很好 谢谢你的好提示!Root的一个问题是它自己处理stdout/err,所以我认为没有办法告诉它重定向到一个文件。请注意,有一个快捷方式——如果您使用IPython实例(作为shell
传递到\uu init\ucode>),您可以调用shell.ex(cell)
来执行代码。