Я пытаюсь выполнить некоторые манипуляции с файлом ROOT в ноутбуке ipython (ROOT здесь - программа анализа данных ROOT CERN с интерфейсом python). Одной из раздражающих особенностей ROOT является то, что он часто отправляет вывод непосредственно на стандартный вывод вместо того, чтобы возвращать такой вывод в виде строки. Чтобы этот вывод появился в результате в блокноте 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
(например, должен ли я возвращать вывод вместо его печати)? Заранее благодарю за любую помощь!