IPythonノートブックでコードが実行されているかどうかを確認するにはどうすればよいですか?


89

ターミナルPython / IPythonまたはIPythonノートブックで実行した場合に何か違うことをするはずのPythonコード例をいくつか共有したいと思います。

PythonコードがIPythonノートブックで実行されているかどうかを確認するにはどうすればよいですか?


3
グスタボベゼラの答えを受け入れることをお勧めします。現在受け入れられている回答は質問に回答していません。Gustavoの回答は、最新バージョンのJupyterNotebookでも機能する最高スコアの回答です。
マークアメリー

回答:


8

問題は、何を別の方法で実行したいかです。

IPythonで最善を尽くして、カーネルがどの種類のフロントエンドに接続されているかを認識しないようにします。実際には、カーネルを同時に多くの異なるフロントエンドに接続することもできます。stderr/outZMQカーネルを使用しているかどうかを確認するためにタイプを確認できたとしても、反対側にあるものを保証するものではありません。フロントエンドがまったくない可能性もあります。

おそらくフロントエンドに依存しない方法でコードを書く必要がありますが、異なるものを表示したい場合は、リッチディスプレイシステム(IPythonのバージョン4.xに固定されたリンク)を使用して、フロントエンドに応じて異なるものを表示できますが、ライブラリではなく、フロントエンドが選択します。


2
上記のIPythonRich DisplaySystemへのリンクが壊れています。現在のドキュメントへのリンクは次のとおりです:ipython.org/ipython-doc/dev/config/integrating.html、およびいくつかの優れた例へのリンクは次のとおり
Who8MyLunch 2014

2
描画モジュールでこのような問題が発生します。図面を保存できるように、 travis -ciの呼び出しmatplotlib.use( "Agg")をインポートする必要があります(stackoverflow.com/questions/4706451/…を参照)。ただし、これによりノートブックに警告生成さます。ユーザー警告:このmatplotlib.useの呼び出し()バックエンドがすでに選択されているため、効果はありません。これを解決する方法は?
ゴウル博士2014年

33
1つの例があります:プログレスバー。Jupyterノートブック端末エミュレーターは\x1b[A(上に移動)などの拡張端末制御文字をサポートしていないため、ネストされたバーを印刷することはできません。ipywidgetsには問題ありません。ネイティブのJupyterウィジェットを使用してプログレスバーを表示できます。ただし、プログレスバーを表示する方法は2つあり、アプリケーションは、互換性のあるバーを調整して印刷するために、表示環境を知りたい場合があります。
華やかな2016年

2
たとえば、IPython configを%matplotlib inlineノートブックとして機能するときに常に実行するように設定しますが、ターミナルでは実行する必要がないためです。
シプリアンTomoiagă

3
これは完全に有効な意見ですが、この回答は実際の質問に対応していません。あなたがそれをどれだけ望んでいたとしても、そうでなければ重要な行動の違いが常にあります。
クリストファーバーバー

72

以下は私のニーズに合った:

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でテストされました。


5
jupyter console、残念ながらget_ipython()、次のインスタンスZMQInteractiveShellも返します
Josh Bode 2017年

7
:誰かがノートブックがグーグルコラボで実行されているか否かを検出するに興味がある場合は、このチェックすることができますget_ipython().__class__.__module__ == "google.colab._shell"
guiferviz

3
これは、ノートブックのコードに対してのみ機能します。関数がインポートされたパッケージに含まれている場合は機能しません。
クリストファーバーバー

4
@ChristopherBarberそれは私が見ているものではありません。この関数をファイルに貼り付けてからJupyterNotebookでtest.py実行するfrom test import isnotebook; print(isnotebook())と、が出力されTrueます。(ノートブックサーバーバージョン5.2.1および6.0.1でテスト済み)
MarkAmery19年

うまくいかないケースもあると思いましたが、残念ながら詳細は覚えていません。おそらくそれはもはや問題ではないか、あるいは私はただ混乱していたのかもしれません。
クリストファーバーバー

41

ノートブックを使用しているかどうかを確認するために、たとえば使用するプログレスバーの種類を決定するときに重要になる可能性があります。これは私にとってはうまくいきました。

def in_ipynb():
    try:
        cfg = get_ipython().config 
        if cfg['IPKernelApp']['parent_appname'] == 'ipython-notebook':
            return True
        else:
            return False
    except NameError:
        return False

6
私のIPython・ノート(IPythonバージョン3.1)では、cfg['IPKernelApp']['parent_appname']あるIPython.config.loader.LazyConfigValueとは比較にならないこれは、True"iypthon-notebook"
デュックス

5
@juanjux get_ipythonは、ノートブックとターミナル/コンソール(プロットに影響します)を区別する必要があるIPython.kernel.zmq.zmqshell.ZMQInteractiveShell場合に備えて、ipynb(Jupyter)とIPython.terminal.interactiveshell.TerminalInteractiveShellターミナルREPLのインスタンスを返します。
ホブ2015年

4
^そのため、あなたは内部置き換えることができますtry:付きブロックreturn str(type(get_ipython())) == "<class 'ipykernel.zmqshell.ZMQInteractiveShell'>"
user2561747

@Duxのように、これは私には機能しません。ノートブックであっても、常にfalseを返します。この答えは、ある種の怠惰な構成読み込みシステムの導入によって時代遅れになったのではないかと思われます。
マークアメリー

また、設定が空のdictとして返される場合があることにも注意してください。その場合、exceptブロックにKeyErrorを追加する必要があります。ただし、GustavoBezerraの回答に基づいたコードを使用する方がおそらく良いでしょう。空の構成を取得してもshell='PyDevTerminalInteractiveShell'、クラス名を検査すると取得します。
hlongmore

29

次のスニペット[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

: ">輸入DEF is_interactive()-cのpythonメインメイン>リターン(メイン'はhasattrないとファイルを)')>(is_interactive印刷する"トゥルー
marscher

3
is_interactive()ノートブックとコンソールを区別しません。
krock 2015年

1
もう1つの注意点として、%runipythonからを発行することは非対話型です。あなたはそれがそうあるべきであると主張することができます、しかしそれはまだ落とし穴です。
dirkjot 2017年

ノートブックでプロトタイピングを行う他の人にとっては、ここで紹介するTillのアプローチの変形が役立つかもしれません。
ウェイン

この回答の後半は役に立ちますが、前半(約is_interactive)は基本的に質問とは無関係のようです。それは疑わしい正しさでもあります。@marscherが指摘しpython -cているように、これが当てはまらない場合でも、使用して実行されたものはすべて「インタラクティブ」モードであると見なされます。自分の答えではないので自分ではやりたくないのですが、前半全体を削除するだけで改善できると思います。
マークアメリー

17

最近、回避策が必要な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']

うーん、私はFedora 23 Jupyterを使用し'Ipython' in sys.modulesていFalseますが、評価は。多分あなたは意味し'IPython' in sys.modulesますか?これはTrue私のJupyter環境にあります。sys.modules辞書も含まれていない'ipykernel'キーを-ノートブック内で実行されているとき。
maxschlepzig 2016年

2
これがこれまでのベストアンサー、IMOです。短くて甘い。
danielpcox

3

Python3.7.3でテスト済み

CPython実装には、__builtins__グローバルの一部として使用できる名前があります。関数globals()で取得できます。
スクリプトがIpython環境で実行されている場合は__IPYTHON__、の属性である必要があります__builtins__
したがって、以下のコードはTrue、Ipythonで実行した場合、またはそれ以外の場合に返されます。False

hasattr(__builtins__,'__IPYTHON__')

2

以下は、の出力を解析する必要なしに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 consolejupyter qtconsoleまたはjupyter notebook
ルークデイビス

2

フロントエンドが多すぎるため、特定のフロントエンドを検出しないようにすることをお勧めします。代わりに、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ます。


私にはうまくいきません-Python3を使用してUbuntuのJupyterNotebookでこれを試すと、get_ipython()が返されます<ipykernel.zmqshell.ZMQInteractiveShell at 0x7f750ba94320>
主人公

このアプローチの問題は、OPの質問「PythonコードがIPythonノートブックで実行されているかどうかを確認するにはどうすればよいですか?」を解決できないことです。(私の強調)。IPythonシェルはノートブックではありませんが、PyCharmのPythonコンソールで実行すると、がget_ipython() is not None返されTrueます。
hlongmore

うーん、jupyterとvoilaで実行しているかどうかをどのように検出できますか?
NTG

2

あなたがしなければならないのはあなたのノートブックの始めにこれらの2つのセルを置くことです:

セル1 :(「コード」としてマーク):

is_notebook = True

セル2 :(「生のNBConvert」としてマーク):

is_notebook = False

最初のセルは常に実行されますが、2番目のセルはノートブックをPythonスクリプトとしてエクスポートした場合にのみ実行されます。

後で確認できます。

if is_notebook:
    notebook_code()
else:
    script_code()

お役に立てれば。


2

このようなものはどうですか:

import sys

inJupyter = sys.argv[-1].endswith('json')

print(inJupyter);

1

私の知る限り、ここには3種類のipythonが使用されています ipykernel

  1. ipython qtconsole (略して「qtipython」)
  2. スパイダーのIPython(略して「スパイダー」)
  3. jupyterノートブックのIPython(略して「jn」)

使用'spyder' in sys.modulesするとスパイダーを区別できます

しかし、qtipythonとjnの場合、原因を区別するのは困難です

それらは同じsys.modulesIPython構成を持っています: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を区別します


0

Django Shell Plusを使用してIPythonを起動していますが、「ノートブックでの実行」をDjango設定値として使用できるようにしたいと考えていました。get_ipython()設定をロードするときに利用できないので、これを使用します(これは防弾ではありませんが、使用されているローカル開発環境には十分です):

import sys

if '--notebook' in sys.argv:
    ENVIRONMENT = "notebook"
else:
    ENVIRONMENT = "dev"

0

Jupyter Notebookを制御できると仮定すると、次のことができます。

  1. これをコードのフラグとして使用するセルに環境値を設定します。そのセル(または除外するすべてのセル)に一意のコメントを配置します

    #exclude_from_export
    %set_env is_jupyter = 1

  2. ノートブックをPythonスクリプトとしてエクスポートして、別のコンテキストで使用します。エクスポートでは、コメント付きのセルと、それに続く環境値を設定するコードが除外されます。注:your_notebook.ipynbを実際のノートブックファイルの名前に置き換えてください。

    jupyter nbconvert --to script --RegexRemovePreprocessor.patterns = "['^#exclude_from_export']" your_notebook.ipynb

これにより、jupyter環境フラグが設定されていないファイルが生成され、それを使用して決定論的に実行されるコードが可能になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.