我想在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