IPython Notebookでモジュールから出力したHTMLタグを有効にする方法

ラベル:

LibreOffice5(5)unoinsp.pyでAPIリファレンスへのリンクを付けるで手こずったネタです。IPython はAnacondaでインストールした3.2.0を使っています(linuxBean14.04(88)LibreOffice5をIPython Notebookから操作する)。

IPython Notebookにインポートするモジュールは再読込されない

まず最初にインポートするモジュールを再読込するautoreloadエクステンションを有効にしておきます。
これはこの記事の最後に解説しますが、HTMLタグの出力とは関係なく、単にこの記事を書くための設定です。
In [1]:
%load_ext autoreload
%autoreload 1
%aimport html_sample
%aimport
Modules to reload:
html_sample

Modules to skip:

これでhtml_sampleというモジュールについてはセルにインポートするたびに再読込されます。
逆に言えばそれ以外のモジュールは1回読み込んだあとはモジュールを編集しようともkernelを再起動するまでは変更部分は反映されません。

入力セルのHTMLタグを有効にするのは簡単

入力セルに打ち込んだHTMLタグは%%htmlでタグを有効にして出力できます。
In [2]:
%%html
<a href="http://p--q.blogspot.jp/">p--q</a>
この方法は入力セル全体がHTMLとして解釈されます。
Pythonで作成したHTMLタグのみ解釈させたいときはHTMLメソッドを使います。
In [3]:
from IPython.core.display import HTML
HTML('<a href="http://p--q.blogspot.jp/">p--q</a>')
Out[3]:
この2つの方法はpython - How to embed HTML into iPython output? - Stack Overflowの質問に書いてありました。
私がやりたかったのはPythonでprint('<a href="http://p--q.blogspot.jp/">p--q</a>')
としたものを出力セルに出力させることでしたので、この回答のないQ&AのQだけで事足りたと思いました。

モジュールから出力セルにHTMLを出力するときはdisplayが必要

ところがモジュールからHTMLで出力しようとして問題にぶち当たりました。
In [ ]:
from IPython.core.display import HTML
def html_out(id):
    HTML('<a href="http://' + id + '.blogspot.jp/">' + id + '</a>')
これをhtml_sample.pyファイルにいれてインポートしてhtml_out()を実行してみます。
In [4]:
import html_sample
html_sample.html_out("p--q")
なにも出力されません。
In [ ]:
from IPython.display import display, HTML
def html_out(id):
    display(HTML('<a href="http://' + id + '.blogspot.jp/">' + id + '</a>'))
インポートしたモジュールにあるprint()の出力がIPython Notebookの出力セルになっているのに対してHTML()の出力先は出力セル以外に出力されていたようです。
IPython.displayからIPython.display.displayをインポートしてIPython.display.HTML()の結果をdisplayしてやると結果が出力されました。
In [5]:
import html_sample
html_sample.html_out("p--q")
これで問題が解決しました。

モジュールを更新したときにkernelを再起動せずに済ます方法

IPython Notebookにインポートしているモジュールの更新を反映させるためには、インポートしているセルを再実行させるだけではダメで、IPython Notebookのkernel restartが毎回必要です。
それを知らずにやっていて無駄な時間を費やしました。
さらにkernelを再起動すればよいとわかってからも、再起動に時間がかかって時間を費やしました。
それで調べたところモジュールを再読み込みしてくれる方法がありました。
まずIPython extensionsのautorelaodをロードします。
In [1]:
%load_ext autoreload
%aimportで現在モジュールの再読み込みの状態がわかります。
In [2]:
%aimport
Modules to reload:


Modules to skip:

デフォルトでは再読み込みするモジュールもそうしないモジュールも指定されていません。
In [3]:
%autoreload 2
%aimport
Modules to reload:
all-except-skipped

Modules to skip:

%autoreload 2で除外指定したモジュール以外を再読み込みするようになります。
%autoreloadだけでも除外指定したモジュール以外を再読込するようですが、%autoreloadはその時だけ再読込するのに対して%autoreload 2はPythonコマンドを実行するたびに再読込するようです。
In [4]:
%aimport -html_sample
%aimport
Modules to reload:
all-except-skipped

Modules to skip:
html_sample
%aimport -モジュール名 これで再読み込みしないモジュールが指定できました。
In [5]:
%autoreload 1
%aimport
Modules to reload:


Modules to skip:
html_sample
%autoreload 1にすると2のときとは逆に指定したモジュールのみ再読み込みします。
In [6]:
%aimport html_sample
%aimport
Modules to reload:
html_sample

Modules to skip:

%autoreload モジュール名 で再読込するモジュールが指定できます。
In [7]:
%autoreload 0
%autoreload 0で再読み込みを無効にします。

参考にしたサイト


python - How to embed HTML into iPython output? - Stack Overflow
入力セルのHTMLタグを出力セルで有効にする方法。

IPython - Development - Printing HTML within IPython Notebook / IPython-specific prettyprint?
読み込んだモジュールから出力セルにHTMLタグを出力する方法。

Module: display — IPython 3.2.1 documentation
IPython.displayモジュールのマニュアル。

IPython extensions — IPython 3.2.1 documentation
IPython extensionsのautoreloadを使うとインポートの再読み込みの設定ができます。

The IPython API — IPython 4.0.0 documentation
IPython4もIPythonと同様にIPython.displayモジュールがあります。

IPython extensions — IPython 4.0.0 documentation
IPythonのエクステンションのマニュアル。
PR

0 件のコメント:

コメントを投稿