IPython नोटबुक में कोड निष्पादित होने पर मैं कैसे जांच सकता हूं?


89

मेरे पास कुछ पायथन कोड उदाहरण हैं जिन्हें मैं साझा करना चाहूंगा, अगर टर्मिनल पायथन / आईपीथॉन में या आईपीथॉन नोटबुक में निष्पादित किया जाए तो कुछ अलग करना चाहिए।

अगर यह IPython नोटबुक में चल रहा है तो मैं अपने पायथन कोड से कैसे जांच कर सकता हूं?


3
मेरा सुझाव है कि गुस्तावो बीज़र्रा का उत्तर स्वीकार करना । वर्तमान में स्वीकृत उत्तर प्रश्न का उत्तर नहीं देता है, और गुस्तावो का उत्तर उच्चतम-स्कोर वाला उत्तर है जो अभी भी ज्यूपिटर नोटबुक के नवीनतम संस्करण में काम करता है।
मार्क अमेरी

जवाबों:


8

सवाल यह है कि आप अलग तरीके से क्या करना चाहते हैं।

हम IPython में अपनी पूरी कोशिश करते हैं कि कर्नेल को यह जानने से रोकें कि किस तरह का फ्रंटेंड जुड़ा हुआ है, और वास्तव में आप कर्नेल को एक ही समय में कई अलग-अलग फ्रंटेंड्स से कनेक्ट कर सकते हैं। यहां तक ​​कि अगर आप stderr/outएक झामुमो कर्नेल में हैं या नहीं, यह जानने के लिए कि आप किस तरह से झांक सकते हैं , यह इस बात की गारंटी नहीं देता कि आपके पास दूसरी तरफ क्या है। तुम भी कोई सामने नहीं हो सकता था।

आपको अपना कोड शायद एक स्वतंत्र तरीके से लिखना चाहिए, लेकिन यदि आप अलग-अलग चीजों को प्रदर्शित करना चाहते हैं, तो आप फ्रंटएंड के आधार पर अलग-अलग चीजों को प्रदर्शित करने के लिए रिच डिस्प्ले सिस्टम (आईपीथॉन के संस्करण 4.x पर पिन किए गए लिंक) का उपयोग कर सकते हैं , लेकिन सीमांत का चयन करेंगे, न कि पुस्तकालय का।


2
IPython रिच डिस्प्ले सिस्टम के ऊपर का लिंक टूटा हुआ है। यहाँ वर्तमान दस्तावेज़ के लिए लिंक है: ipython.org/ipython-doc/dev/config/integrating.html , और यहाँ कुछ महान उदाहरणों की एक कड़ी है: nbviewer.ipython.org/gayub/ipython/ipython/blob/master/ …
Who8MyLunch

2
मुझे अपने ड्राइंग मॉड्यूल में इस तरह की समस्या है । मैं आयात कॉल matplotlib.use ( "Agg") की जरूरत है ट्रैविस-ci के लिए वहाँ की बचत चित्र (देखें अनुमति देने के लिए stackoverflow.com/questions/4706451/... ) लेकिन इस एक चेतावनी उत्पन्न नोटबुक में UserWarning: matplotlib.use को इस कॉल () का कोई प्रभाव नहीं है क्योंकि बैकएंड पहले से ही चुना गया है; इसे कैसे हल करें?
डॉ। गोलू

33
मेरे पास एक उदाहरण है: प्रगति बार। जुपिटर नोटबुक टर्मिनल एमुलेटर विस्तारित टर्मिनल नियंत्रण वर्णों का समर्थन नहीं करता है जैसे कि \x1b[A(ऊपर जाना), इसलिए नेस्टेड बार को प्रिंट करना संभव नहीं है । Ipywidgets के साथ कोई समस्या नहीं है , हम प्रगति बार प्रदर्शित करने के लिए देशी Jupyter विजेट का उपयोग कर सकते हैं। लेकिन फिर हमारे पास प्रगति पट्टी प्रदर्शित करने के दो अलग-अलग साधन हैं, और एक एप्लिकेशन यह जानना चाह सकता है कि संगत बार को अनुकूलित और प्रिंट करने के लिए प्रदर्शन वातावरण क्या है।
विशाल

2
उदाहरण के लिए, मैं IPython config को हमेशा चलाने के लिए सेट करना चाहता हूं %matplotlib inlineजब यह नोटबुक के रूप में कार्य करता है, लेकिन टर्मिनल में नहीं, क्योंकि इसकी आवश्यकता नहीं है।
सिप्रियन टोमोयागू

3
हालांकि यह पूरी तरह से मान्य राय है, लेकिन यह उत्तर वास्तविक प्रश्न को संबोधित नहीं करता है। कोई फर्क नहीं पड़ता कि आप कितना चाहते हैं अन्यथा यह हमेशा व्यवहार में अंतर होगा जो मायने रखता है।
क्रिस्टोफर बार्बर

72

निम्नलिखित ने मेरी जरूरतों के लिए काम किया:

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 के साथ किया गया था।


5
पर jupyter console, दुर्भाग्य से get_ipython()एक उदाहरण ZMQInteractiveShellभी देता है
जोश बोडे

7
अगर किसी को यह पता लगाने में दिलचस्पी है कि क्या Google Colab पर नोटबुक चल रही है या नहीं, तो आप इसे देख सकते हैं:get_ipython().__class__.__module__ == "google.colab._shell"
guiferviz

3
यह केवल नोटबुक में कोड के लिए काम करता है। यह काम नहीं करता है यदि फ़ंक्शन एक आयातित पैकेज में है।
क्रिस्टोफर बार्बर

4
@ChristopherBarber वह नहीं है जो मैं देख रहा हूँ। अगर मैं इस फंक्शन को फाइल में पेस्ट करता हूं test.pyतो from test import isnotebook; print(isnotebook())ज्यूपिटर नोटबुक में चलाएं, यह प्रिंट करता है True। (नोटबुक सर्वर संस्करणों 5.2.1 और 6.0.1 पर परीक्षण किया गया।)
मार्क अमेरी

मुझे लगा कि कुछ मामला है जो मेरे लिए काम नहीं करता था, लेकिन दुर्भाग्य से मुझे विवरण याद नहीं है। शायद अब यह कोई समस्या नहीं है या शायद मैं सिर्फ भ्रमित था।
क्रिस्टोफर बार्बर

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']एक है IPython.config.loader.LazyConfigValue, जो की तुलना नहीं करता है Trueके साथ"iypthon-notebook"
Dux

5
@juanjux get_ipython IPython.kernel.zmq.zmqshell.ZMQInteractiveShellipynb (Jupyter) और IPython.terminal.interactiveshell.TerminalInteractiveShellएक टर्मिनल REPL में एक उदाहरण देता है , अगर आपको नोटबुक और टर्मिनल / कंसोल (जो प्लॉटिंग को प्रभावित करता है) के बीच अंतर करने की आवश्यकता होती है।
हॉब्स

4
^ इसलिए आप tryब्लॉक को अंदर से बदल सकते हैं :return str(type(get_ipython())) == "<class 'ipykernel.zmqshell.ZMQInteractiveShell'>"
user2561747

@ डक्स की तरह, यह मेरे लिए काम नहीं करता है; यह हमेशा झूठ बोलता है, यहां तक ​​कि एक नोटबुक में भी। संदेह है कि यह उत्तर कुछ प्रकार के आलसी विन्यास लोडिंग सिस्टम की शुरूआत के साथ अप्रचलित हो गया।
मार्क अमेरी

यह भी ध्यान दें कि आपका कॉन्फिगर एक खाली तानाशाही के रूप में वापस आ सकता है, इस स्थिति में आपको की-ब्लॉक के अलावा KeyError को जोड़ना होगा। हालांकि गुस्तावो बीज़र्रा के जवाब के आधार पर कोड का उपयोग करना बेहतर है। भले ही मुझे खाली कॉन्फ़िगर मिले, shell='PyDevTerminalInteractiveShell'लेकिन क्लास के नाम का निरीक्षण करने पर मुझे मिल जाता है।
hlongmore

29

आप जाँच सकते हैं कि क्या अजगर निम्नलिखित स्निपेट के साथ इंटरैक्टिव मोड में है [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

python -c "def is_interactive ():> आयात मुख्य के रूप में मुख्य> रिटर्न नहीं hasattr (मुख्य, ' फ़ाइल ')> प्रिंट is_interactive ()" True
marscher

3
is_interactive()नोटबुक और कंसोल के बीच अंतर नहीं करता है।
5

1
एक और चेतावनी, %runipython से जारी करना गैर-संवादात्मक है। आप तर्क कर सकते हैं कि यह होना चाहिए, लेकिन यह अभी भी एक पकड़ है।
बजे

नोटबुक में अन्य प्रोटोटाइप के लिए, टिल्ल के दृष्टिकोण का वैरिएंट यहाँ चित्रित किया गया हो सकता है।
वेन

इस उत्तर का उत्तरार्ध उपयोगी है, लेकिन पहला आधा (लगभग is_interactive) मुझे मूल रूप से प्रश्न के लिए अप्रासंगिक लगता है। यह संदिग्ध शुद्धता का भी है; जैसा कि @marscher बताते हैं, यह python -c"इंटरेक्टिव" मोड में होने के बावजूद कुछ भी चलाने को मायने रखता है, हालांकि यह सच नहीं है। मैं इसे स्वयं नहीं करना चाहता क्योंकि यह मेरा उत्तर नहीं है, लेकिन मुझे लगता है कि उत्तर के पूरे पहले भाग को हटा देने से ही इसमें सुधार होगा।
मार्क अमेरी

17

हाल ही में मैंने ज्यूपिटर नोटबुक में एक बग का सामना किया , जिसे वर्कअराउंड की आवश्यकता है, और मैं अन्य गोले में कार्यक्षमता खोए बिना ऐसा करना चाहता था। मैंने महसूस किया कि केफ्लेविच का समाधान इस मामले में काम नहीं करता है, क्योंकि 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']

हम्म, मैं फेडोरा 23 ज्यूपिटर का उपयोग कर रहा हूं, और वहां का 'Ipython' in sys.modulesमूल्यांकन करता है False। शायद आपका मतलब है 'IPython' in sys.modules? यह Trueमेरे जुपिटर के माहौल में है। sys.modulesशब्दकोश भी शामिल नहीं है 'ipykernel'कुंजी - जब एक नोटबुक के अंदर चल रहा है।
maxschlepzig

2
यह अब तक का सबसे अच्छा जवाब है, IMO। छोटा एवं सुन्दर।
danielpcox

3

अजगर 3.7.3 के लिए परीक्षण किया गया

CPython कार्यान्वयन __builtins__में उनके ग्लोबल्स के भाग के रूप में उपलब्ध नाम है जो btw। फ़ंक्शन ग्लोबल्स () द्वारा पुनर्प्राप्त किया जा सकता है।
यदि कोई स्क्रिप्ट Ipython वातावरण में चल रही है, तो __IPYTHON__उसका एक गुण होना चाहिए __builtins__
इसलिए नीचे का कोड रिटर्न करता है Trueअगर इफिथॉन के तहत चलाया जाता है या यह देता है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
ल्यूक डेविस

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


मेरे लिए काम नहीं करता है - जब मैं प्यूथन 3 के साथ उबंटू में जुपिटर नोटबुक में यह कोशिश करता हूं, तो get_ipython()रिटर्न करता है <ipykernel.zmqshell.ZMQInteractiveShell at 0x7f750ba94320>
नायक

इस दृष्टिकोण के साथ समस्या यह है कि यह ओपी के सवाल को हल नहीं करता है, "मैं अपने पायथन कोड से कैसे जांच कर सकता हूं अगर यह आईपीथॉन नोटबुक में चल रहा है ?" (जोर मेरा)। IPython शेल एक नोटबुक नहीं है, लेकिन जब मैं इसे PyCharm में अपने Python Console में चलाता हूं, तो मुझे get_ipython() is not Noneवापस मिल जाता है True
2

हम्म, मैं कैसे पता लगा सकता हूं कि मैं ज्यूपिटर बनाम वॉइला पर चल रहा हूं?
ntg

2

आपको बस इतना करना है कि अपनी नोटबुक की शुरुआत में इन दो कोशिकाओं को रखें:

सेल 1: ("कोड" के रूप में चिह्नित):

is_notebook = True

सेल 2: ("रॉ NBConvert" के रूप में चिह्नित):

is_notebook = False

पहली सेल हमेशा निष्पादित की जाएगी, लेकिन दूसरी सेल केवल तभी निष्पादित की जाएगी जब आप नोटबुक को पायथन स्क्रिप्ट के रूप में निर्यात करेंगे।

बाद में, आप देख सकते हैं:

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 (संक्षेप में "क्यूटीपायथन")
  2. स्पाइडर में आईपीथॉन (संक्षेप में "स्पाइडर")
  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]

मेरा 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


0

मैं IPython को लॉन्च करने के लिए Django शेल प्लस का उपयोग कर रहा हूं, और मैं Django सेटिंग्स मान के रूप में 'नोटबुक में चल रहा है' उपलब्ध करना चाहता था। get_ipython()सेटिंग लोड करते समय उपलब्ध नहीं है, इसलिए मैं इसका उपयोग करता हूं (जो बुलेटप्रूफ नहीं है, लेकिन स्थानीय विकास वातावरण के लिए पर्याप्त अच्छा है):

import sys

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

0

यह मानते हुए कि आपके पास बृहस्पति नोटबुक का नियंत्रण है:

  1. एक सेल में एक पर्यावरण मूल्य निर्धारित करें जो इसे आपके कोड में एक ध्वज के रूप में उपयोग करता है । उस सेल में एक अनूठी टिप्पणी रखें (या उन सभी कोशिकाओं को जिन्हें आप बाहर करना चाहते हैं)

    # बहिष्कृत_फ्रेम_एक्सपोर्ट
    % set_env is_jupyter = 1

  2. एक अलग संदर्भ में उपयोग की जाने वाली अजगर लिपि के रूप में नोटबुक को निर्यात करें। निर्यात टिप्पणी सेल (एस) को बाहर करेगा और बाद में कोड जो पर्यावरण मूल्य निर्धारित करता है। नोट: अपने_notebook.ipynb को बदलें अपनी वास्तविक नोटबुक फ़ाइल के नाम के साथ को ।

    jupyter nbconvert --to script --RegexRemovePreprocessor.patterns = "['^ # # oute_from_export']" your_notebook.ipynb

यह एक ऐसी फ़ाइल उत्पन्न करेगा जिसमें कोड के लिए अनुमति देने वाले ज्यूपिटर पर्यावरण ध्वज नहीं होगा जो इसे नियतात्मक रूप से निष्पादित करने के लिए उपयोग करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.