11

I am currently using Python3 in Jupyter Notebook and I just ran into a keyword exit. What does this keyword do ?

with open("some_file.txt") as f:
    for lines in f:
        print(lines)
        exit
Seungho Lee
  • 1,068
  • 4
  • 16
  • 42

3 Answers3

9

The exit lines in your loop do nothing. Why they do nothing is a bit more complicated than the usual reason exit would do nothing in Python, though.


Normally, exit on a line by its own wouldn't exit Python. At most, in interactive mode, it would print a message telling you how to quit Python (message implemented in _sitebuiltins.Quitter.__repr__):

>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit

IPython does something different. Among the many extra systems IPython has for interactive convenience is a system to autocall instances of a certain type, IPython.core.autocall.IPyAutocall. (This is similar to but distinct from the %autocall magic.)

In IPython, exit and quit are set to instances of IPython.core.autocall.ExitAutocall, a subclass of IPyAutocall. IPython recognizes objects of this type, so when a line containing just exit or quit is executed, IPython actually exits.

In [1]: exit
[IPython dies here]

A Jupyter notebook's IPython kernel has exit and quit set to instances of the very closely related IPython.core.autocall.ZMQExitAutocall, which has some extra functionality to support a keep_kernel argument, but is otherwise the same.

This functionality only triggers when a line referring to the autocallable object is the entire content of the cell, though. Inside a loop, the autocall functionality doesn't trigger, so we're back to nothing happening.

In fact, even less happens than what would happen in normal interactive mode - in a normal, non-IPython interactive session, this loop would print the "Use exit()..." message on each iteration, due to differences in how IPython and the regular interactive mode handle expression auto-printing.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • It also has an optional parameter to keep the kernel running - https://github.com/jupyter/jupyter_console/issues/48#issuecomment-299674959 – Kingsley Dec 07 '18 at 20:08
  • @Kingsley which I assume Spyder is doing in my case, and I suspect Jupyter would invoke by default. I can't see much use for this other than a wipe of the namespace otherwise. If you actually shut the IPython kernel down then you can't do a whole lot – roganjosh Dec 07 '18 at 20:09
  • Actually, it might be a part of [IPython.core.autocall.ZMQExitAutocall](https://ipython.readthedocs.io/en/stable/api/generated/IPython.core.autocall.html#IPython.core.autocall.ZMQExitAutocall) The behaviour and the parameter seems to support it. – Paritosh Singh Dec 07 '18 at 20:20
4

When exit (sic, with no parentheses) is used in iPython in a loop or a branch of a conditional statement, it is doing nothing because it is simply a reference to an instance of IPython.core.autocall.ExitAutocall:

for i in range(10): 
    exit 
print(i)
# 9

if i==9: 
   exit 
   print(exit)    
# <IPython.core.autocall.ExitAutocall object at 0x7f76ad78a4a8>      

It does not restart the kernel:

print(i)
# 9

However, when used on the command line alone, it is treated as a kind of magic (though without a %) and terminates the kernel.

DYZ
  • 55,249
  • 10
  • 64
  • 93
3

On my simple test,
Cell 1
a = 3
Cell 2
exit
cell 3
print(a)

resulted in

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-3f786850e387> in <module>
----> 1 a

NameError: name 'a' is not defined

exit just kills the kernel that the notebook is relying on for execution.

Interestingly enough however, There seems to be a parameter you can pass to modify that behaviour as well.

Test 2: Cell 1
a = 3
Cell 2
exit(keep_kernel=True)
cell 3
print(a) resulted in 3

EDIT: And looks like @user2357112's answer fills in the missing pieces.
EDIT2: Actually, it seems to be an instance of IPython.core.autocall.ZMQExitAutocall

 class IPython.core.autocall.ZMQExitAutocall(ip=None)

    Bases: IPython.core.autocall.ExitAutocall

    Exit IPython. Autocallable, so it needn’t be explicitly called.
    Parameters: keep_kernel (bool) – If True, leave the kernel alive. Otherwise, tell the kernel to exit too (default).
Paritosh Singh
  • 6,034
  • 2
  • 14
  • 33
  • Ah nice. I was trying to work out what this might do. So it looks like, from your test, it wipes the namespace? – roganjosh Dec 07 '18 at 20:03
  • 1
    In Spyder it is restarting the IPython kernel. You already have my upvote, but I think you could do with adding the documentation for this (my lame way of backing out of a fiddly google search :P) – roganjosh Dec 07 '18 at 20:05
  • 2
    mhm, i am actually really intrigued by this behaviour, tracking down the documentation atm, however check the edit. @roganjosh It makes me suspect it is doing something not just with namespaces. – Paritosh Singh Dec 07 '18 at 20:07