itsource

IPython 노트북에서 코드가 실행되는지 확인하려면 어떻게 해야 합니까?

mycopycode 2023. 7. 21. 21:35
반응형

IPython 노트북에서 코드가 실행되는지 확인하려면 어떻게 해야 합니까?

저는 터미널 Python/IPython 또는 IPython 노트북에서 실행될 경우 다른 작업을 수행해야 하는 Python 코드 예제를 공유하고 싶습니다.

IPthon 노트북에서 실행 중인 파이썬 코드를 어떻게 확인할 수 있습니까?

다음은 제 요구사항에 부합합니다.

get_ipython().__class__.__name__

를 합니다.'TerminalInteractiveShell' 아피톤단에말기의이▁on.'ZMQInteractiveShell' AND 콘솔NameError는 일반 Python 인터프리터에서 사용할 수 있습니다.get_ipython()IPython이 시작될 때 기본적으로 글로벌 네임스페이스에서 사용할 수 있습니다.

간단한 기능으로 포장:

def is_notebook() -> bool:
    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로 테스트되었습니다.

편집: 이것은 더 새로운 파이썬/에서 2022년에도 여전히 잘 작동합니다.IPython/Jupiter/OS 버전

다음 스니펫 [1]을 사용하여 python이 대화형 모드에 있는지 확인할 수 있습니다.

def is_interactive():
    import __main__ as main
    return not hasattr(main, '__file__')

저는 노트북에서 프로토타이핑을 많이 하기 때문에 이 방법이 매우 유용하다는 것을 알게 되었습니다.테스트 목적으로 기본 매개 변수를 사용합니다.그지렇않다면으음매변읽습다니수를개서에eters▁from▁param다▁the▁otherwise▁read▁i니의 매개변수를 읽습니다.sys.argv.

from sys import argv

if is_interactive():
    params = [<list of default parameters>]
else:
    params = argv[1:]

의 구현 후 다음 코드를 사용하여 노트북에 있는지 여부를 확인할 수 있습니다.

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
    except AttributeError:
        return False
    return True

예를 들어 사용할 진행 표시줄을 결정할 때 중요할 수 있는 노트북에 있는지 확인하려면 다음과 같이 해야 합니다.

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()노트북에서만 사용할 수 있으며 가져온 모듈에서는 사용할 수 없습니다.그래서 모듈에서 주피터 노트북에서 가져와 사용하는지 여부를 감지하는 방법을 찾았습니다.

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']

python 3.7.3에 대해 테스트됨

Cython 구현에는 다음과 같은 이름이 있습니다.__builtins__함수 글로벌로 검색할 수 있는 글로벌의 일부로 사용할 수 있습니다.
Ipython은 Ipython과 동일합니다.__IPYTHON__이어야 합니다.__builtins__.
아래 는 따라서아래코반환다니됩가드다니▁below를 반환합니다.TrueIpython 아래에서 실행되거나 그렇지 않으면 제공됩니다.False

hasattr(__builtins__,'__IPYTHON__')

문제는 무엇을 다르게 실행하고 싶은지입니다.

우리는 IPython에서 커널이 어떤 종류의 프론트엔드에 연결되어 있는지 알 수 없도록 최선을 다하고 있으며, 실제로 커널을 여러 다른 프론트엔드에 동시에 연결할 수도 있습니다.의 유형을 살짝 볼 수 있더라도stderr/out당신이 ZMQ 커널에 있는지 아닌지를 알기 위해서, 그것은 당신이 다른 쪽에 가지고 있는 것을 보장하지 않습니다.심지어 당신은 프런트 엔드가 전혀 없을 수도 있습니다.

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

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

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

is_notebook = True

셀 2: ("원시 NBC 변환"으로 표시됨):

is_notebook = False

첫 번째 셀은 항상 실행되지만 두 번째 셀은 Python 스크립트로 노트북을 내보낼 때만 실행됩니다.

나중에 다음을 확인할 수 있습니다.

if is_notebook:
    notebook_code()
else:
    script_code()

이게 도움이 되길 바랍니다.

매우 간단하고 효율적인 솔루션은 다음과 같이 콜 스택의 상단이 IPython 환경을 참조하는지 확인하는 것입니다.

import traceback

def is_in_notebook():
    rstk = traceback.extract_stack(limit=1)[0]
    return rstk[0].startswith("<ipython")

이 코드는 IPython 또는 Jupyter에서 Python 2 및 3 모두에서 작동하며 환경을 확인, 설정 또는 변경할 필요가 없습니다.

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

특정 프런트 엔드가 너무 많기 때문에 탐지를 피하는 것이 좋습니다.대신 iPython 환경에서 실행 중인지 테스트하면 됩니다.

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

는 위의내이반됩니다환용다▁return니됩을 반환합니다.False를 호출하는 running_from_ipython일반적인 파이썬 명령줄에서. 노트북,허브, 쉘, 하면 주터노, 주터허, iPython 쉘, Google Colab 가 반환됩니다.True.

제가 알기로는, 여기에 사용된 3가지 종류의 이피톤이 있습니다.ipykernel

  1. ipython qtconsole의 줄임말)("qtipython")
  2. 스파이더의 Ipython("스파이더"의 줄임말
  3. 주피터 노트북의 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]

저의 큐티피톤은 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)

소스 코드는 다음과 같습니다: 탐지 파이썬 환경, 특히 스파이더 구별하기, 주피터 노트북, Qtconsole.py

나는 IPython을 런칭하기 위해 Django Shell Plus를 사용하고 있으며, '노트북에서 실행'을 Django 설정 값으로 사용할 수 있도록 하고 싶었습니다.get_ipython()설정을 로드할 때 사용할 수 없기 때문에 다음을 사용합니다(방탄성은 아니지만 사용되는 로컬 개발 환경에 충분히 적합함).

import sys

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

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

  1. 이 값을 코드의 플래그로 사용하는 셀에 환경 값을 설정합니다.해당 셀(또는 제외할 모든 셀)에 고유한 주석을 작성합니다.


    %set_computer=1

  2. 다른 컨텍스트에서 사용할 python 스크립트로 노트북을 내보냅니다.내보내기에서는 주석이 달린 셀과 그 후 환경 값을 설정하는 코드를 제외합니다.참고:_notebook.ipynb를 실제 노트북 파일의 이름으로 바꿉니다.

    jupyter nbconvert --스크립트로 --RegexRemovePreprocessor.patterns=include'^# exclude_from_export']" your_surve.ipynb

이렇게 하면 주피터 환경 플래그가 설정되지 않은 파일이 생성되어 해당 파일을 사용하는 코드가 결정적으로 실행될 수 있습니다.

다음과 같은 것은 어떻습니까?

import sys

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

print(inJupyter);

다음은 파이썬 코드가 실행되는 위치를 알려줍니다.Jupyter 독립 실행형, Python 독립 실행형, Spyder, VSCode 또는 Jupyter가 VSCode 내에서 검색되지 않습니다.

import os
import IPython as ipy

# add string sources only
sources = str(os.environ.keys()) + \
          ipy.get_ipython().__class__.__name__

# make pattern of unique keys
checks = {'SPYDER': 'Spyder', 'QTIPYTHON': 'qt IPython', 'VSCODE': 
          'VS Code', 'ZMQINTERACTIVEshell': 'Jupyter', }

results = []
msg = []

for k, v in checks.items():
    u = str(k.upper())
    if u in sources.upper():
        results.append(checks[k])

if not results:
    msg.append("Unknown IDE")
else:
    msg.append("Program working ")
    while results:
        msg.append(f"in {results.pop()}")
        if results:
            msg.append(' with')

print(''.join(msg))

할 수 있습니다.eval('__IPYTHON__')pydantic에서 차용:

def in_ipython() -> bool:
    """
    Check whether we're in an ipython environment, including jupyter notebooks.
    """
    try:
        eval('__IPYTHON__')
    except NameError:
        return False
    else:  # pragma: no cover
        return True

상위 프로세스 확인

지금까지 제게 효과가 있었던 유일한 해결책은 psutil을 사용하여 상위 프로세스를 확인하는 것입니다.

import psutil
def runninginJupyterNotebook():
    for i in psutil.Process().parent().cmdline():
        if "jupyter-notebook" in i:
            return True
    else:
        return False

또는 한 줄로 변수를 설정할 수 있습니다.

RUNNING_IN_JUPYTER = any(["jupyter-notebook" in i for i in psutil.Process().parent().cmdline()])

RUNNING_IN_JUPYTER이라True주피터 노트북을 실행하는 경우.

Colab 노트북을 실행하는 경우에도 마찬가지입니다.

MacOS에서

import psutil
def runninginJupyterNotebook():
    for i in psutil.Process().parent().cmdline():
        if "jupyter-notebook" in i:
            return True
    else:
        return False

또는 한 줄로 변수를 설정할 수 있습니다.

RUNNING_IN_JUPYTER = any([i.endswith("bin/jupyter-notebook") for i in psutil.Process().parent().cmdline()])

다른 솔루션과의 비교:

get_ipython().__class__.__name__

사용하는 모든 get_ipython()Qt 콘솔에서 실행 중인지 여부와 상관없는 경우에만 작동합니다.

학점: https://stackoverflow.com/a/65498256/2132157

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

반응형