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


89

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

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


3
Gustavo Bezerra의 답변을 수락하는 것이 좋습니다 . 현재 허용되는 답변은 질문에 대한 답변이 아니며 Gustavo의 답변은 최신 버전의 Jupyter Notebook에서 여전히 작동하는 가장 높은 점수를받은 답변입니다.
Mark Amery

답변:


9

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

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

코드를 프런트 엔드 독립적 인 방식으로 작성해야하지만, 다른 것을 표시 하려면 리치 디스플레이 시스템 (IPython 버전 4.x에 고정 된 링크) 을 사용하여 프런트 엔드에 따라 다른 것을 표시 할 수 있습니다. 프런트 엔드는 라이브러리가 아닌 선택합니다.


2
IPython Rich Display System에 대한 위의 링크가 끊어졌습니다. 다음은 현재 문서에 대한 링크입니다 : ipython.org/ipython-doc/dev/config/integrating.html , 여기에 몇 가지 훌륭한 예제에 대한 링크가 있습니다 : nbviewer.ipython.org/github/ipython/ipython/blob/master/ …
Who8MyLunch

2
드로잉 모듈 에서 이와 같은 문제가 있습니다 . 도면을 저장할 수 있도록 travis-ci에 대한 call matplotlib.use ( "Agg")를 가져와야합니다 ( stackoverflow.com/questions/4706451/… 참조 ) 그러나 노트북에 경고 생성됩니다. UserWarning : This call to matplotlib.use () 백엔드가 이미 선택 되었기 때문에 효과가 없습니다. 이것을 해결하는 방법?
Dr. Goulu

30
한 가지 예가 있습니다. 진행률 표시 줄입니다. Jupyter 노트북 터미널 에뮬레이터는 \x1b[A(move up) 과 같은 확장 터미널 제어 문자를 지원하지 않으므로 중첩 된 막대 를 인쇄 할 수 없습니다 . ipywidgets 에는 문제가 없습니다. 기본 Jupyter 위젯을 사용하여 진행률 표시 줄을 표시 할 수 있습니다. 그러나 진행률 표시 줄을 표시하는 두 가지 다른 방법이 있으며 응용 프로그램은 호환되는 표시 줄을 조정하고 인쇄하기 위해 디스플레이 환경이 무엇인지 알고 싶어 할 수 있습니다.
gaborous

2
예를 들어, IPython 구성 %matplotlib inline이 노트북으로 작동 할 때 항상 실행되도록 설정하고 싶지만 터미널에서는 필요하지 않기 때문에 실행됩니다.
Ciprian Tomoiagă

3
이것은 완벽하게 유효한 의견이지만이 답변은 실제 질문을 다루지 않습니다. 아무리 원하든 상관없이 행동에는 항상 중요한 차이가있을 것입니다.
Christopher Barber

69

다음은 내 요구에 적합했습니다.

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로 테스트되었습니다.


5
켜짐 jupyter console, 불행히도 get_ipython()의 인스턴스를 반환 ZMQInteractiveShell
조쉬 보데에게

7
: 사람이 노트북이 구글 Colab에서 실행 여부를 검출에 관심이 있다면 당신이 확인할 수 있습니다get_ipython().__class__.__module__ == "google.colab._shell"
guiferviz

3
이것은 노트북의 코드에서만 작동합니다. 함수가 가져온 패키지에 있으면 작동하지 않습니다.
Christopher Barber

4
@ChristopherBarber 그게 내가 보는 것이 아닙니다. 이 함수를 파일에 붙여 test.py넣은 다음 from test import isnotebook; print(isnotebook())Jupyter Notebook에서 실행 하면 True. (노트북 서버 버전 5.2.1 및 6.0.1에서 테스트되었습니다.)
Mark Amery

저에게 맞지 않는 케이스가 있다고 생각했는데 안타깝게도 세부 사항이 기억 나지 않습니다. 아마도 그것은 더 이상 문제가 아니거나 아마도 혼란 스러웠을 것입니다.
Christopher Barber

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']A는 IPython.config.loader.LazyConfigValue비교하지 않는, True"iypthon-notebook"
DUX

5
@juanjux get_ipython은 노트북과 터미널 / 콘솔을 구분해야하는 경우 (플로팅에 영향을주는 IPython.kernel.zmq.zmqshell.ZMQInteractiveShell) ipynb (Jupyter) 및 IPython.terminal.interactiveshell.TerminalInteractiveShell터미널 REPL 의 인스턴스를 반환합니다 .
hobs

4
^ 그러므로 당신은 내부 대체 할 수있다 try:와 블록return str(type(get_ipython())) == "<class 'ipykernel.zmqshell.ZMQInteractiveShell'>"
user2561747

@Dux와 마찬가지로 이것은 나를 위해 작동하지 않습니다. 노트북에서도 항상 false를 반환합니다. 이 답변이 일종의 지연 구성 로딩 시스템의 도입으로 쓸모 없게 된 것으로 의심됩니다.
Mark Amery

또한 구성이 빈 dict로 돌아올 수 있으며,이 경우 except 블록에 KeyError를 추가해야합니다. 그러나 Gustavo Bezerra의 답변을 기반으로 한 코드를 사용하는 것이 더 좋습니다. 빈 구성을 얻더라도 shell='PyDevTerminalInteractiveShell'클래스 이름을 검사 할 때 나타납니다.
hlongmore

28

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

python -c "def is_interactive () :> import main as main> return not hasattr (main, ' file ')> print is_interactive ()"True
marscher

3
is_interactive()노트북과 콘솔을 구분하지 않습니다.
krock

1
%runipython에서를 발행하는 또 다른주의 사항 은 비대화 형입니다. 그래야한다고 주장 할 수 있지만 여전히 문제입니다.
dirkjot

노트북에서 다른 프로토 타이핑을하는 경우 여기에 소개 된 Till의 접근 방식의 변형 이 유용 할 수 있습니다.
Wayne

이 답변의 후반부는 유용하지만 전반부 (약 is_interactive)는 기본적으로 질문과 관련이없는 것 같습니다. 그것은 또한 모호한 정확성입니다. @marscher가 지적했듯이, 이것이 python -c사실이 아니더라도 "대화 형"모드로 실행 되는 모든 것을 계산 합니다. 내 대답이 아니기 때문에 직접하고 싶지는 않지만, 대답의 전반부 전체를 삭제하는 것만으로도 개선 될 것이라고 생각합니다.
Mark Amery

17

최근 에 해결 방법이 필요한 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']

흠, 난 페도라 23 Jupyter를 사용하여, 거기 있어요 'Ipython' in sys.modules에 평가합니다 False. 아마도 당신은 의미 'IPython' in sys.modules합니까? 이것은 True내 Jupyter 환경에 있습니다. 또한 sys.modules사전에는 'ipykernel'노트북 내부에서 실행할 때 키 가 포함되어 있지 않습니다 .
maxschlepzig

2
이것은 지금까지 최고의 답변입니다. IMO. 짧고 달다.
danielpcox

3

Python 3.7.3 용으로 테스트 됨

CPython 구현에는 __builtins__btw라는 전역의 일부로 사용할 수 있는 이름이 있습니다. 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 console, jupyter qtconsole또는 jupyter notebook.
Luke Davis

2

너무 많기 때문에 특정 프런트 엔드를 감지하지 않는 것이 좋습니다 . 대신 iPython 환경에서 실행 중인지 테스트 할 수 있습니다.

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

위는 일반적인 파이썬 명령 줄에서 False호출하는 경우 반환 됩니다 running_from_ipython. Jupyter Notebook, JupyterHub, iPython shell, Google Colab 등에서 호출하면 True.


나를 위해 작동하지 않습니다 - 나는 Python3, 우분투에 Jupyter 노트북이를하려고하면 get_ipython()돌아갑니다 <ipykernel.zmqshell.ZMQInteractiveShell at 0x7f750ba94320>.
주인공

이 접근법의 문제점은 OP의 질문 인 "IPython 노트북 에서 실행중인 경우 Python 코드에서 어떻게 확인할 수 있습니까?"라는 질문을 해결하지 못한다는 것입니다. (강조 내). IPython 쉘은 노트북이 아니라 내가 PyCharm 내 파이썬 콘솔에서 실행하면, 내가받을 get_ipython() is not None반환 True.
hlongmore

음, jupyter 대 voila에서 실행 중인지 어떻게 감지 할 수 있습니까?
ntg

2

노트북 시작 부분에 다음 두 개의 셀을 배치하기 만하면됩니다.

셀 1 : ( "코드"로 표시) :

is_notebook = True

셀 2 : ( "Raw NBConvert"로 표시) :

is_notebook = False

첫 번째 셀은 항상 실행되지만 두 번째 셀은 노트북을 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.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 구분


0

Django Shell Plus를 사용하여 IPython을 시작하고 있으며 Django 설정 값으로 '노트북에서 실행'을 사용할 수 있도록 만들고 싶었습니다. get_ipython()설정을로드 할 때 사용할 수 없으므로 이것을 사용합니다 (방탄은 아니지만 사용되는 로컬 개발 환경에 충분합니다).

import sys

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

0

Jupyter 노트북을 제어 할 수 있다고 가정하면 다음을 수행 할 수 있습니다.

  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.