program story

IPython 노트북에서 코드가 실행되었는지 어떻게 확인할 수 있습니까?

inputbox 2020. 11. 24. 07:56
반응형

IPython 노트북에서 코드가 실행되었는지 어떻게 확인할 수 있습니까?


터미널 Python / IPython 또는 IPython 노트북에서 실행되면 다른 작업을 수행해야하는 Python 코드 예제가 있습니다.

Python 코드가 IPython 노트북에서 실행 중인지 어떻게 확인할 수 있습니까?


문제는 무엇을 다르게 실행하길 원하는가입니다.

우리는 IPython에서 최선을 다해 커널이 어떤 종류의 프런트 엔드에 연결되어 있는지 알지 못하도록합니다. 실제로 커널을 여러 다른 프런트 엔드에 동시에 연결할 수도 있습니다. stderr/outZMQ 커널에 있는지 여부를 알기 위해 유형을 엿볼 수 있더라도 다른쪽에있는 것을 보장하지 않습니다. 프런트 엔드가 전혀 없을 수도 있습니다.

코드를 프런트 엔드 독립적 인 방식으로 작성해야하지만 다른 것을 표시하려는 경우 리치 디스플레이 시스템 (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__

'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

위의 내용은 macOS 10.12 및 Ubuntu 14.04.4 LTS에서 Python 3.5.2, IPython 5.1.0 및 Jupyter 4.2.1로 테스트되었습니다.


다음 스 니펫 [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

최근 에 해결 방법이 필요한 Jupyter 노트북에서 버그 가 발생하여 다른 셸의 기능을 잃지 않고이 작업을 수행하고 싶었습니다. 이 경우 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']

다음은 출력을 구문 분석 할 필요없이 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

내가 아는 한, 여기에 사용 된 3 종류의 ipython이 있습니다. ipykernel

  1. ipython qtconsole (줄여서 "qtipython")
  2. 스파이더의 IPython (줄여서 "스파이더")
  3. jupyter 노트북의 IPython (줄여서 "jn")

사용 'spyder' in sys.modules스파이더을 구별 할 수

그러나 qtipython과 jn의 경우 원인을 구별하기가 어렵습니다.

동일 sys.modules하고 동일한 IPython 구성이 있습니다.get_ipython().config

qtipython과 jn 사이에 차이점이 있습니다.

os.getpid()IPython 쉘에서 먼저 실행 하여 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의 이름보다 깁니다.

따라서 다음 코드로 모든 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 구분


I would recommend avoiding to detect specific frontend because there are too many of them. Instead you can just test if you are running from within iPython environment:

def is_running_from_ipython():
    from IPython import get_ipython
    return get_ipython() is not None

Above will return False if you are invoking running_from_ipython from usual python command line. When you invoke it from Jupyter Notebook, JupyterHub, iPython shell, Google Colab etc then it will return True.


I am using Django Shell Plus to launch IPython, and I wanted to make 'running in notebook' available as a Django settings value. get_ipython() is not available when loading settings, so I use this (which is not bulletproof, but good enough for the local development environments it's used in):

import sys

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

Tested for python 3.7.3

CPython implementations have the name __builtins__ available as part of their globals which btw. can be retrieved by the function globals().
If a script is running in an Ipython environment then __IPYTON__ should be an attribute of __builtins__.
The code below therefore returns True if run under Ipython else it gives False

hasattr(__builtins__,'__IPYTHON__')

참고URL : https://stackoverflow.com/questions/15411967/how-can-i-check-if-code-is-executed-in-the-ipython-notebook

반응형