今回は Python の実行環境が Jupyter Notebook か否かを判定する方法について。 ベースのアイデアは以下の Stackoverflow からお借りした。
使った環境は次の通り。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.13.6 BuildVersion: 17G3025 $ python -V Python 3.6.7 $ pip list --format=columns | grep notebook notebook 5.7.0
下準備
まずは今回使用するパッケージをインストールしておく。
$ pip install notebook ipywidgets tqdm
実行環境が Jupyter Notebook か否かをチェックする関数
早速だけど実行環境をチェックする関数は次の通り。
def is_env_notebook(): """Determine wheather is the environment Jupyter Notebook""" if 'get_ipython' not in globals(): # Python shell return False env_name = get_ipython().__class__.__name__ if env_name == 'TerminalInteractiveShell': # IPython shell return False # Jupyter Notebook return True
この関数を使うと、例えば次のように環境ごとにインポートするパッケージや関数を切り替えることができる。
if is_env_notebook(): # Jupyter Notebook environment from tqdm import tqdm_notebook as tqdm else: # Other shells from tqdm import tdqm
関数の動作原理について
ここからは関数がどのように動作するかを確認していく。
まずは Jupyter Notebook を起動しておこう。
$ jupyter-notebook
新しい Notebook を作ったら、以下のコードを使ってグローバルスコープのオブジェクトを全て表示してみよう。
import pprint pprint.pprint(globals())
すると、例えば次のような出力になる。
この中に get_ipython()
という関数があることが確認できる。
{'In': ['', 'import pprint\npprint.pprint(globals())'], 'Out': {}, '_': '', '__': '', '___': '', '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '__doc__': 'Automatically created module for IPython interactive environment', '__loader__': None, '__name__': '__main__', '__package__': None, '__spec__': None, '_dh': ['/Users/amedama/Documents/temporary'], '_i': '', '_i1': 'import pprint\npprint.pprint(globals())', '_ih': ['', 'import pprint\npprint.pprint(globals())'], '_ii': '', '_iii': '', '_oh': {}, 'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x104733c18>, 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x104733dd8>>, 'pprint': <module 'pprint' from '/Users/amedama/.pyenv/versions/3.6.7/lib/python3.6/pprint.py'>, 'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x104733c18>}
では、次に別のターミナルから通常の Python インタプリタを起動しよう。
$ python
先ほどと同じコードを実行してみる。
すると、こちらには get_ipython()
関数が見当たらない。
その他にも、いくつか Jupyter Notebook の環境ではあったオブジェクトが無いことも分かる。
>>> from pprint import pprint >>> pprint(globals()) {'__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__name__': '__main__', '__package__': None, '__spec__': None, 'pprint': <function pprint at 0x10b08de18>}
この特徴を元に、環境を一次切り分けできる。
少なくとも get_ipython()
関数がグローバルスコープになければ Jupyter Notebook の環境ではなさそう。
$ python ... >>> 'get_ipython' in globals() False
ただし、これだけだと上手くいかない場合がある。
それは IPython の環境で、IPython のインタプリタを起動するとグローバルスコープに get_ipython()
関数が見つかる。
$ ipython ... In [1]: 'get_ipython' in globals() Out[1]: True
ただし、一つ救いがあって get_ipython()
関数の返り値が Jupyter Notebook とは異なっている。
IPython のインタプリタで返されるのは TerminalInteractiveShell
というクラスのインスタンス。
In [2]: get_ipython() Out[2]: <IPython.terminal.interactiveshell.TerminalInteractiveShell at 0x1080a7710>
それに対し Jupyter Notebook では ZMQInteractiveShell
というクラスのインスタンスになっている。
$ jupyter-notebook ... In [1]: 'get_ipython' in globals() Out[1]: True In [2]: get_ipython() Out[2]: <ipykernel.zmqshell.ZMQInteractiveShell at 0x1081f0198>
そのため、クラスの違いを元に環境を識別できる。
いじょう。
スマートPythonプログラミング: Pythonのより良い書き方を学ぶ
- 作者: もみじあめ
- 発売日: 2016/03/12
- メディア: Kindle版
- この商品を含むブログ (1件) を見る