मेरे पास कुछ पायथन कोड उदाहरण हैं जिन्हें मैं साझा करना चाहूंगा, अगर टर्मिनल पायथन / आईपीथॉन में या आईपीथॉन नोटबुक में निष्पादित किया जाए तो कुछ अलग करना चाहिए।
अगर यह IPython नोटबुक में चल रहा है तो मैं अपने पायथन कोड से कैसे जांच कर सकता हूं?
मेरे पास कुछ पायथन कोड उदाहरण हैं जिन्हें मैं साझा करना चाहूंगा, अगर टर्मिनल पायथन / आईपीथॉन में या आईपीथॉन नोटबुक में निष्पादित किया जाए तो कुछ अलग करना चाहिए।
अगर यह IPython नोटबुक में चल रहा है तो मैं अपने पायथन कोड से कैसे जांच कर सकता हूं?
जवाबों:
सवाल यह है कि आप अलग तरीके से क्या करना चाहते हैं।
हम IPython में अपनी पूरी कोशिश करते हैं कि कर्नेल को यह जानने से रोकें कि किस तरह का फ्रंटेंड जुड़ा हुआ है, और वास्तव में आप कर्नेल को एक ही समय में कई अलग-अलग फ्रंटेंड्स से कनेक्ट कर सकते हैं। यहां तक कि अगर आप stderr/out
एक झामुमो कर्नेल में हैं या नहीं, यह जानने के लिए कि आप किस तरह से झांक सकते हैं , यह इस बात की गारंटी नहीं देता कि आपके पास दूसरी तरफ क्या है। तुम भी कोई सामने नहीं हो सकता था।
आपको अपना कोड शायद एक स्वतंत्र तरीके से लिखना चाहिए, लेकिन यदि आप अलग-अलग चीजों को प्रदर्शित करना चाहते हैं, तो आप फ्रंटएंड के आधार पर अलग-अलग चीजों को प्रदर्शित करने के लिए रिच डिस्प्ले सिस्टम (आईपीथॉन के संस्करण 4.x पर पिन किए गए लिंक) का उपयोग कर सकते हैं , लेकिन सीमांत का चयन करेंगे, न कि पुस्तकालय का।
\x1b[A
(ऊपर जाना), इसलिए नेस्टेड बार को प्रिंट करना संभव नहीं है । Ipywidgets के साथ कोई समस्या नहीं है , हम प्रगति बार प्रदर्शित करने के लिए देशी Jupyter विजेट का उपयोग कर सकते हैं। लेकिन फिर हमारे पास प्रगति पट्टी प्रदर्शित करने के दो अलग-अलग साधन हैं, और एक एप्लिकेशन यह जानना चाह सकता है कि संगत बार को अनुकूलित और प्रिंट करने के लिए प्रदर्शन वातावरण क्या है।
%matplotlib inline
जब यह नोटबुक के रूप में कार्य करता है, लेकिन टर्मिनल में नहीं, क्योंकि इसकी आवश्यकता नहीं है।
निम्नलिखित ने मेरी जरूरतों के लिए काम किया:
get_ipython().__class__.__name__
यह 'TerminalInteractiveShell'
एक टर्मिनल IPython, 'ZMQInteractiveShell'
Jupyter (नोटबुक और qtconsole) और NameError
एक नियमित पायथन दुभाषिया पर विफल ( ) पर लौटता है । यह विधि 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())
ज्यूपिटर नोटबुक में चलाएं, यह प्रिंट करता है 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']
एक है 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] :
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
"इंटरेक्टिव" मोड में होने के बावजूद कुछ भी चलाने को मायने रखता है, हालांकि यह सच नहीं है। मैं इसे स्वयं नहीं करना चाहता क्योंकि यह मेरा उत्तर नहीं है, लेकिन मुझे लगता है कि उत्तर के पूरे पहले भाग को हटा देने से ही इसमें सुधार होगा।
हाल ही में मैंने ज्यूपिटर नोटबुक में एक बग का सामना किया , जिसे वर्कअराउंड की आवश्यकता है, और मैं अन्य गोले में कार्यक्षमता खोए बिना ऐसा करना चाहता था। मैंने महसूस किया कि केफ्लेविच का समाधान इस मामले में काम नहीं करता है, क्योंकि 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
यदि यह पर्याप्त रूप से मजबूत है तो टिप्पणियों की सराहना की जाती है।
इसी तरह से क्लाइंट और आईपीथॉन संस्करण के बारे में कुछ जानकारी प्राप्त करना संभव है:
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
मेरे जुपिटर के माहौल में है। sys.modules
शब्दकोश भी शामिल नहीं है 'ipykernel'
कुंजी - जब एक नोटबुक के अंदर चल रहा है।
अजगर 3.7.3 के लिए परीक्षण किया गया
CPython कार्यान्वयन __builtins__
में उनके ग्लोबल्स के भाग के रूप में उपलब्ध नाम है जो btw। फ़ंक्शन ग्लोबल्स () द्वारा पुनर्प्राप्त किया जा सकता है।
यदि कोई स्क्रिप्ट Ipython वातावरण में चल रही है, तो __IPYTHON__
उसका एक गुण होना चाहिए __builtins__
।
इसलिए नीचे का कोड रिटर्न करता है True
अगर इफिथॉन के तहत चलाया जाता है या यह देता हैFalse
hasattr(__builtins__,'__IPYTHON__')
निम्नलिखित आउटपुट को पार्स करने की आवश्यकता के बिना 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
।
आपको बस इतना करना है कि अपनी नोटबुक की शुरुआत में इन दो कोशिकाओं को रखें:
सेल 1: ("कोड" के रूप में चिह्नित):
is_notebook = True
सेल 2: ("रॉ NBConvert" के रूप में चिह्नित):
is_notebook = False
पहली सेल हमेशा निष्पादित की जाएगी, लेकिन दूसरी सेल केवल तभी निष्पादित की जाएगी जब आप नोटबुक को पायथन स्क्रिप्ट के रूप में निर्यात करेंगे।
बाद में, आप देख सकते हैं:
if is_notebook:
notebook_code()
else:
script_code()
उम्मीद है की यह मदद करेगा।
इस जैसे किसी और के बारे में क्या राय है:
import sys
inJupyter = sys.argv[-1].endswith('json')
print(inJupyter);
जहाँ तक मुझे पता है, यहाँ 3 प्रकार के ipython का उपयोग किया गया है ipykernel
ipython qtconsole
(संक्षेप में "क्यूटीपायथन")उपयोग '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 की तुलना में लंबा है
इसलिए, हम निम्नलिखित कोड द्वारा सभी पायथन पर्यावरण का पता लगा सकते हैं:
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)
स्रोत कोड यहां हैं: डिटेक्शन पायथन एनवायरनमेंट, विशेष रूप से स्पाइडर, जुपिटर नोटबुक, Qtconcam.py
मैं IPython को लॉन्च करने के लिए Django शेल प्लस का उपयोग कर रहा हूं, और मैं Django सेटिंग्स मान के रूप में 'नोटबुक में चल रहा है' उपलब्ध करना चाहता था। get_ipython()
सेटिंग लोड करते समय उपलब्ध नहीं है, इसलिए मैं इसका उपयोग करता हूं (जो बुलेटप्रूफ नहीं है, लेकिन स्थानीय विकास वातावरण के लिए पर्याप्त अच्छा है):
import sys
if '--notebook' in sys.argv:
ENVIRONMENT = "notebook"
else:
ENVIRONMENT = "dev"
यह मानते हुए कि आपके पास बृहस्पति नोटबुक का नियंत्रण है:
एक सेल में एक पर्यावरण मूल्य निर्धारित करें जो इसे आपके कोड में एक ध्वज के रूप में उपयोग करता है । उस सेल में एक अनूठी टिप्पणी रखें (या उन सभी कोशिकाओं को जिन्हें आप बाहर करना चाहते हैं)
# बहिष्कृत_फ्रेम_एक्सपोर्ट
% set_env is_jupyter = 1
एक अलग संदर्भ में उपयोग की जाने वाली अजगर लिपि के रूप में नोटबुक को निर्यात करें। निर्यात टिप्पणी सेल (एस) को बाहर करेगा और बाद में कोड जो पर्यावरण मूल्य निर्धारित करता है। नोट: अपने_notebook.ipynb को बदलें अपनी वास्तविक नोटबुक फ़ाइल के नाम के साथ को ।
jupyter nbconvert --to script --RegexRemovePreprocessor.patterns = "['^ # # oute_from_export']" your_notebook.ipynb
यह एक ऐसी फ़ाइल उत्पन्न करेगा जिसमें कोड के लिए अनुमति देने वाले ज्यूपिटर पर्यावरण ध्वज नहीं होगा जो इसे नियतात्मक रूप से निष्पादित करने के लिए उपयोग करता है।