ターミナルPython / IPythonまたはIPythonノートブックで実行した場合に何か違うことをするはずのPythonコード例をいくつか共有したいと思います。
PythonコードがIPythonノートブックで実行されているかどうかを確認するにはどうすればよいですか?
回答:
問題は、何を別の方法で実行したいかです。
IPythonで最善を尽くして、カーネルがどの種類のフロントエンドに接続されているかを認識しないようにします。実際には、カーネルを同時に多くの異なるフロントエンドに接続することもできます。stderr/out
ZMQカーネルを使用しているかどうかを確認するためにタイプを確認できたとしても、反対側にあるものを保証するものではありません。フロントエンドがまったくない可能性もあります。
おそらくフロントエンドに依存しない方法でコードを書く必要がありますが、異なるものを表示したい場合は、リッチディスプレイシステム(IPythonのバージョン4.xに固定されたリンク)を使用して、フロントエンドに応じて異なるものを表示できますが、ライブラリではなく、フロントエンドが選択します。
\x1b[A
(上に移動)などの拡張端末制御文字をサポートしていないため、ネストされたバーを印刷することはできません。ipywidgetsには問題ありません。ネイティブのJupyterウィジェットを使用してプログレスバーを表示できます。ただし、プログレスバーを表示する方法は2つあり、アプリケーションは、互換性のあるバーを調整して印刷するために、表示環境を知りたい場合があります。
%matplotlib inline
ノートブックとして機能するときに常に実行するように設定しますが、ターミナルでは実行する必要がないためです。
以下は私のニーズに合った:
get_ipython().__class__.__name__
'TerminalInteractiveShell'
ターミナルIPython、'ZMQInteractiveShell'
Jupyter(ノートブックおよびqtconsole)に戻りNameError
、通常のPythonインタープリターでは失敗します()。このメソッド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
上記は、macOS10.12およびUbuntu14.04.4LTS上のPython3.5.2、IPython 5.1.0、およびJupyter4.2.1でテストされました。
jupyter console
、残念ながらget_ipython()
、次のインスタンスZMQInteractiveShell
も返します
get_ipython().__class__.__module__ == "google.colab._shell"
test.py
実行するfrom test import isnotebook; print(isnotebook())
と、が出力されTrue
ます。(ノートブックサーバーバージョン5.2.1および6.0.1でテスト済み)
ノートブックを使用しているかどうかを確認するために、たとえば使用するプログレスバーの種類を決定するときに重要になる可能性があります。これは私にとってはうまくいきました。
def in_ipynb():
try:
cfg = get_ipython().config
if cfg['IPKernelApp']['parent_appname'] == 'ipython-notebook':
return True
else:
return False
except NameError:
return False
cfg['IPKernelApp']['parent_appname']
あるIPython.config.loader.LazyConfigValue
とは比較にならないこれは、True
と"iypthon-notebook"
IPython.kernel.zmq.zmqshell.ZMQInteractiveShell
場合に備えて、ipynb(Jupyter)とIPython.terminal.interactiveshell.TerminalInteractiveShell
ターミナルREPLのインスタンスを返します。
try
:付きブロックreturn str(type(get_ipython())) == "<class 'ipykernel.zmqshell.ZMQInteractiveShell'>"
shell='PyDevTerminalInteractiveShell'
、クラス名を検査すると取得します。
次のスニペット[1]を使用して、Pythonがインタラクティブモードになっているかどうかを確認できます。
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
is_interactive()
ノートブックとコンソールを区別しません。
%run
ipythonからを発行することは非対話型です。あなたはそれがそうあるべきであると主張することができます、しかしそれはまだ落とし穴です。
is_interactive
)は基本的に質問とは無関係のようです。それは疑わしい正しさでもあります。@marscherが指摘しpython -c
ているように、これが当てはまらない場合でも、使用して実行されたものはすべて「インタラクティブ」モードであると見なされます。自分の答えではないので自分ではやりたくないのですが、前半全体を削除するだけで改善できると思います。
最近、回避策が必要なJupyter Notebookのバグに遭遇しました。他のシェルの機能を失うことなく、これを実行したいと思いました。インポートされたモジュールからではなく、ノートブックから直接利用できるため、この場合、keflavichのソリューションは機能しないことに気付きましたget_ipython()
。そこで、モジュールから、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']
'Ipython' in sys.modules
ていFalse
ますが、評価は。多分あなたは意味し'IPython' in sys.modules
ますか?これはTrue
私のJupyter環境にあります。sys.modules
辞書も含まれていない'ipykernel'
キーを-ノートブック内で実行されているとき。
以下は、の出力を解析する必要なしに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
jupyter
それがあるかどうかjupyter console
、jupyter qtconsole
またはjupyter notebook
。
フロントエンドが多すぎるため、特定のフロントエンドを検出しないようにすることをお勧めします。代わりに、iPython環境内から実行しているかどうかをテストできます。
def is_running_from_ipython():
from IPython import get_ipython
return get_ipython() is not None
通常のPythonコマンドラインからFalse
呼び出す場合は、上記が返されますrunning_from_ipython
。Jupyter Notebook、JupyterHub、iPythonシェル、Google Colabなどから呼び出すと、が返されTrue
ます。
get_ipython()
が返されます<ipykernel.zmqshell.ZMQInteractiveShell at 0x7f750ba94320>
。
get_ipython() is not None
返されTrue
ます。
このようなものはどうですか:
import sys
inJupyter = sys.argv[-1].endswith('json')
print(inJupyter);
私の知る限り、ここには3種類のipythonが使用されています ipykernel
ipython qtconsole
(略して「qtipython」)使用'spyder' in sys.modules
するとスパイダーを区別できます
しかし、qtipythonとjnの場合、原因を区別するのは困難です
それらは同じsys.modules
IPython構成を持っています:get_ipython().config
qtipythonとjnの違いを見つけました:
os.getpid()
IPythonシェルで最初に実行してpid番号を取得する
次に実行します ps -ef|grep [pid number]
私のqtipythonpidは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
私のjnpidは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環境を自動検出できます。
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を区別します
Django Shell Plusを使用してIPythonを起動していますが、「ノートブックでの実行」をDjango設定値として使用できるようにしたいと考えていました。get_ipython()
設定をロードするときに利用できないので、これを使用します(これは防弾ではありませんが、使用されているローカル開発環境には十分です):
import sys
if '--notebook' in sys.argv:
ENVIRONMENT = "notebook"
else:
ENVIRONMENT = "dev"
Jupyter Notebookを制御できると仮定すると、次のことができます。
これをコードのフラグとして使用するセルに環境値を設定します。そのセル(または除外するすべてのセル)に一意のコメントを配置します
#exclude_from_export
%set_env is_jupyter = 1
ノートブックをPythonスクリプトとしてエクスポートして、別のコンテキストで使用します。エクスポートでは、コメント付きのセルと、それに続く環境値を設定するコードが除外されます。注:your_notebook.ipynbを実際のノートブックファイルの名前に置き換えてください。
jupyter nbconvert --to script --RegexRemovePreprocessor.patterns = "['^#exclude_from_export']" your_notebook.ipynb
これにより、jupyter環境フラグが設定されていないファイルが生成され、それを使用して決定論的に実行されるコードが可能になります。