ターミナルPython/IPythonまたはIPythonノートブックで実行した場合、何か別のことを行う必要があるPythonコード例を共有します。
PythonコードがIPythonノートブックで実行されているかどうかを確認するにはどうすればよいですか?
問題は、何を違う方法で実行するかです。
私たちはIPythonで最善を尽くし、カーネルがどの種類のフロントエンドに接続されているかを認識できないようにします。実際には、同時に多くの異なるフロントエンドにカーネルを接続することもできます。 stderr/out
のタイプを覗いてZMQカーネルにいるかどうかを確認できたとしても、反対側にあるものを保証するものではありません。フロントエンドがまったくない場合もあります。
おそらく、フロントエンドに依存しない方法でコードを記述する必要がありますが、異なるものを表示したい場合は、 豊富な表示システム(IPythonのバージョン4.xに固定されたリンク) を使用して異なるものを表示できますフロントエンドに依存しますが、ライブラリではなくフロントエンドが選択します。
ノートブックを使用しているかどうかを確認するには、これは重要です。使用するプログレスバーの種類を決定するとき、これは私のために働いた:
def in_ipynb():
try:
cfg = get_ipython().config
if cfg['IPKernelApp']['parent_appname'] == 'ipython-notebook':
return True
else:
return False
except NameError:
return False
以下は私のニーズに合っていました:
_get_ipython().__class__.__name__
_
ターミナルIPythonでは_'TerminalInteractiveShell'
_、Jupyterでは_'ZMQInteractiveShell'
_(ノートブックAND qtconsole)を返し、通常のPythonインタープリターでは失敗します(NameError
)。 method get_python()
は、IPythonの起動時にデフォルトでグローバルネームスペースで使用できるようです。
単純な関数でラップする:
_def isnotebook():
try:
Shell = get_ipython().__class__.__name__
if Shell == 'ZMQInteractiveShell':
return True # Jupyter notebook or qtconsole
Elif Shell == 'TerminalInteractiveShell':
return False # Terminal running IPython
else:
return False # Other type (?)
except NameError:
return False # Probably standard Python interpreter
_
上記は、Python 3.5.2、IPython 5.1.0およびmacOS 10.12およびUbuntu 14.04.4 LTS上のJupyter 4.2.1でテストされました。
以下のスニペットを使用して、python)がinteractiveモードになっているかどうかを確認できます [1] :
def is_interactive():
import __main__ as main
return not hasattr(main, '__file__')
私はノートブックで多くのプロトタイピングを行うので、この方法は非常に便利だと感じました。テストのために、デフォルトのパラメーターを使用します。それ以外の場合は、sys.argv
からパラメーターを読み取ります。
from sys import argv
if is_interactive():
params = [<list of default parameters>]
else:
params = argv[1:]
autonotebook
の実装に続いて、次のコードを使用してノートブックにいるかどうかを確認できます。
def in_notebook():
try:
from IPython import get_ipython
if 'IPKernelApp' not in get_ipython().config: # pragma: no cover
return False
except ImportError:
return False
return True
最近、回避策が必要な Jupyterノートブックのバグ に遭遇し、他のシェルの機能を失うことなくこれを実行したいと考えました。 get_ipython()
はノートブックからのみ直接利用でき、インポートされたモジュールからは利用できないため、この場合 keflavichのソリューション は機能しません。だから、モジュールがJupyterノートブックからインポートされて使用されているかどうかをモジュールから検出する方法を見つけました。
import sys
def in_notebook():
"""
Returns ``True`` if the module is running in IPython kernel,
``False`` if in IPython Shell or other Python Shell.
"""
return 'ipykernel' in sys.modules
# later I found out this:
def ipython_info():
ip = False
if 'ipykernel' in sys.modules:
ip = 'notebook'
Elif 'IPython' in sys.modules:
ip = 'terminal'
return ip
これが十分に堅牢であれば、コメントを歓迎します。
同様に、クライアントに関する情報やIPythonバージョンも取得できます。
import sys
if 'ipykernel' in sys.modules:
ip = sys.modules['ipykernel']
ip_version = ip.version_info
ip_client = ip.write_connection_file.__module__.split('.')[0]
# and this might be useful too:
ip_version = IPython.utils.sysinfo.get_sys_info()['ipython_version']
以下は、 https://stackoverflow.com/a/50234148/1491619 の場合をキャプチャします。ps
の出力を解析する必要はありません。
def pythonshell():
"""Determine python Shell
pythonshell() returns
'Shell' (started python on command line using "python")
'ipython' (started ipython on command line using "ipython")
'ipython-notebook' (e.g., running in Spyder or started with "ipython qtconsole")
'jupyter-notebook' (running in a Jupyter notebook)
See also https://stackoverflow.com/a/37661854
"""
import os
env = os.environ
Shell = 'Shell'
program = os.path.basename(env['_'])
if 'jupyter-notebook' in program:
Shell = 'jupyter-notebook'
Elif 'JPY_PARENT_PID' in env or 'ipython' in program:
Shell = 'ipython'
if 'JPY_PARENT_PID' in env:
Shell = 'ipython-notebook'
return Shell
私が知る限り、ここにはipykernel
を使用した3種類のipythonがあります
ipython qtconsole
_(略して「qtipython」)_'spyder' in sys.modules
_を使用するとスパイダーを区別できます
しかし、qtipythonとjnでは原因を区別するのは難しい
同じ_sys.modules
_と同じIPython config:get_ipython().config
を持っています
私はqtipythonとjnの違いを見つけます:
最初にIPythonシェルでos.getpid()
を実行し、pid番号を取得します
次に_ps -ef|grep [pid number]
_を実行します
私のqtipython pidは8699 _yanglei 8699 8693 4 20:31 ? 00:00:01 /home/yanglei/miniconda2/envs/py3/bin/python -m ipykernel_launcher -f /run/user/1000/jupyter/kernel-8693.json
_
私のjn pidは8832 _yanglei 8832 9788 13 20:32 ? 00:00:01 /home/yanglei/miniconda2/bin/python -m ipykernel_launcher -f /run/user/1000/jupyter/kernel-ccb962ec-3cd3-4008-a4b7-805a79576b1b.json
_
qtipythonとjnの違いはipythonのjson名で、jnのjson名はqtipythonのjson名よりも長い
したがって、次のコードですべてのPython Environmentを自動検出できます。
_import sys,os
def jupyterNotebookOrQtConsole():
env = 'Unknow'
cmd = 'ps -ef'
try:
with os.popen(cmd) as stream:
if not py2:
stream = stream._stream
s = stream.read()
pid = os.getpid()
ls = list(filter(lambda l:'jupyter' in l and str(pid) in l.split(' '), s.split('\n')))
if len(ls) == 1:
l = ls[0]
import re
pa = re.compile(r'kernel-([-a-z0-9]*)\.json')
rs = pa.findall(l)
if len(rs):
r = rs[0]
if len(r)<12:
env = 'qtipython'
else :
env = 'jn'
return env
except:
return env
pyv = sys.version_info.major
py3 = (pyv == 3)
py2 = (pyv == 2)
class pyi():
'''
python info
plt : Bool
mean plt avaliable
env :
belong [cmd, cmdipython, qtipython, spyder, jn]
'''
pid = os.getpid()
gui = 'ipykernel' in sys.modules
cmdipython = 'IPython' in sys.modules and not gui
ipython = cmdipython or gui
spyder = 'spyder' in sys.modules
if gui:
env = 'spyder' if spyder else jupyterNotebookOrQtConsole()
else:
env = 'cmdipython' if ipython else 'cmd'
cmd = not ipython
qtipython = env == 'qtipython'
jn = env == 'jn'
plt = gui or 'DISPLAY' in os.environ
print('Python Envronment is %s'%pyi.env)
_
ソースコードは次のとおりです: 検出Python環境、特にSpyder、Jupyterノートブック、Qtconsole.py を区別
それらが多すぎる があるため、特定のフロントエンドの検出を避けることをお勧めします。代わりに、iPython環境内から実行しているかどうかをテストできます。
def is_running_from_ipython():
from IPython import get_ipython
return get_ipython() is not None
上記の例では、通常のpythonコマンドラインからrunning_from_ipython
を呼び出している場合、False
を返します。JupyterNotebook、JupyterHub、iPython Shell、Google Colabなどから呼び出すと、 True
を返します。
Django Shell Plusを使用してIPythonを起動し、[ノートブックで実行]をDjango設定値として利用できるようにしたかった。 get_ipython()
は設定のロード時には使用できないため、これを使用します(防弾ではありませんが、使用されるローカル開発環境には十分です)。
import sys
if '--notebook' in sys.argv:
ENVIRONMENT = "notebook"
else:
ENVIRONMENT = "dev"