터미널 Python / IPython 또는 IPython 노트북에서 실행되면 다른 작업을 수행해야하는 Python 코드 예제가 있습니다.
Python 코드가 IPython 노트북에서 실행 중인지 어떻게 확인할 수 있습니까?
답변:
문제는 무엇을 다르게 실행하기를 원하는가입니다.
우리는 IPython에서 최선을 다해 커널이 어떤 종류의 프런트 엔드에 연결되어 있는지 알지 못하도록합니다. 실제로 커널을 여러 다른 프런트 엔드에 동시에 연결할 수도 있습니다. stderr/out
ZMQ 커널에 있는지 여부를 알기 위해 유형을 엿볼 수 있더라도 다른쪽에있는 것을 보장하지는 않습니다. 프런트 엔드가 전혀 없을 수도 있습니다.
코드를 프런트 엔드 독립적 인 방식으로 작성해야하지만, 다른 것을 표시 하려면 리치 디스플레이 시스템 (IPython 버전 4.x에 고정 된 링크) 을 사용하여 프런트 엔드에 따라 다른 것을 표시 할 수 있습니다. 프런트 엔드는 라이브러리가 아닌 선택합니다.
\x1b[A
(move up) 과 같은 확장 터미널 제어 문자를 지원하지 않으므로 중첩 된 막대 를 인쇄 할 수 없습니다 . ipywidgets 에는 문제가 없습니다. 기본 Jupyter 위젯을 사용하여 진행률 표시 줄을 표시 할 수 있습니다. 그러나 진행률 표시 줄을 표시하는 두 가지 다른 방법이 있으며 응용 프로그램은 호환되는 표시 줄을 조정하고 인쇄하기 위해 디스플레이 환경이 무엇인지 알고 싶어 할 수 있습니다.
%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
위의 내용은 macOS 10.12 및 Ubuntu 14.04.4 LTS에서 Python 3.5.2, IPython 5.1.0 및 Jupyter 4.2.1로 테스트되었습니다.
jupyter console
, 불행히도 get_ipython()
의 인스턴스를 반환 ZMQInteractiveShell
도
get_ipython().__class__.__module__ == "google.colab._shell"
test.py
넣은 다음 from test import isnotebook; print(isnotebook())
Jupyter Notebook에서 실행 하면 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']
A는 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 노트북에서 버그 가 발생하여 다른 셸의 기능을 잃지 않고이 작업을 수행하고 싶었습니다. 이 경우 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
위는 일반적인 파이썬 명령 줄에서 False
호출하는 경우 반환 됩니다 running_from_ipython
. Jupyter Notebook, JupyterHub, iPython shell, 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]
내 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 구분
Django Shell Plus를 사용하여 IPython을 시작하고 있으며 Django 설정 값으로 '노트북에서 실행'을 사용할 수 있도록 만들고 싶었습니다. get_ipython()
설정을로드 할 때 사용할 수 없으므로 이것을 사용합니다 (방탄은 아니지만 사용되는 로컬 개발 환경에 충분합니다).
import sys
if '--notebook' in sys.argv:
ENVIRONMENT = "notebook"
else:
ENVIRONMENT = "dev"
Jupyter 노트북을 제어 할 수 있다고 가정하면 다음을 수행 할 수 있습니다.
이것을 코드에서 플래그 로 사용하는 셀에 환경 값을 설정합니다 . 해당 셀 (또는 제외하려는 모든 셀)에 고유 한 설명을 배치합니다.
# 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 환경 플래그가 설정되지 않은 파일이 생성되어이를 사용하는 코드를 결정적으로 실행할 수 있습니다.