571

In Python, there are two similarly-named functions, exit() and sys.exit(). What's the difference and when should I use one over the other?

2
  • 1
    In case anyone is wondering in light of the passing of return codes, both will correctly have python emit the expected return code. Commented May 4, 2022 at 5:42
  • Also see stackoverflow.com/q/19747371/4014959 Commented Aug 24, 2022 at 15:38

3 Answers 3

622

exit is a helper for the interactive shell - sys.exit is intended for use in programs.

The site module (which is imported automatically during startup, except if the -S command-line option is given) adds several constants to the built-in namespace (e.g. exit). They are useful for the interactive interpreter shell and should not be used in programs.


Technically, they do mostly the same: raising SystemExit. sys.exit does so in sysmodule.c:

static PyObject *
sys_exit(PyObject *self, PyObject *args)
{
    PyObject *exit_code = 0;
    if (!PyArg_UnpackTuple(args, "exit", 0, 1, &exit_code))
        return NULL;
    /* Raise SystemExit so callers may catch it or clean up. */
    PyErr_SetObject(PyExc_SystemExit, exit_code);
   return NULL;
}

While exit is defined in site.py and _sitebuiltins.py, respectively.

class Quitter(object):
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return 'Use %s() or %s to exit' % (self.name, eof)
    def __call__(self, code=None):
        # Shells like IDLE catch the SystemExit, but listen when their
        # stdin wrapper is closed.
        try:
            sys.stdin.close()
        except:
            pass
        raise SystemExit(code)
__builtin__.quit = Quitter('quit')
__builtin__.exit = Quitter('exit')

Note that there is a third exit option, namely os._exit, which exits without calling cleanup handlers, flushing stdio buffers, etc. (and which should normally only be used in the child process after a fork()).

Sign up to request clarification or add additional context in comments.

4 Comments

I suspect that exit(main()) is a common idiom because people don't pick up on the should not be used in programs note. It works fine unless -S is used. A way to make it work even with -S is to specify from sys import *.
@nobar, true, but then you do not really want to use from module import *.
@EvgeniSergeev, I'm not sure what you are asking exactly? It might be an interesting question on its own.
It would be a nice add to this answer to see what issues if any are there for using any of the three exit functions within a "with statement."
61

If I use exit() in a code and run it in the shell, it shows a message asking whether I want to kill the program or not. It's really disturbing. See here

But sys.exit() is better in this case. It closes the program and doesn't create any dialogue box.

1 Comment

This is because it is designed for use in the interactive shell. So even if you want the dialog, sys.exit() should be used inside programs.
16

Solution, Origins, Differences & Speed

Why do we need the exit() / sys.exit() commands?

Usually, the code runs through the lines until the end and the program exits automatically. Occasionally, we would like to ask the program to close before the full cycle run. An example case is when you implement authentication and a user fails to authenticate, in some cases you would like to exit the program.

The exit()

Exits Python.

Maybe you didn't know this, but it's a synonym of quit() and was added after quit() to make python more user friendly. Designed to work with interactive shells.

Usage: Use the built-in exit() out of the box, as is, without importing any library. Just type this:

exit()

Execution Time: 0.03s

Pros:

  • Faster to use (built-in)
  • Works both with python 2.x and python 3.x
  • Fast
  • Can be used exactly like sys.exit() (with the exception)

Cons:

  • No exception message

The sys.exit()

Exits Python and raising the SystemExit exception (requires an import). Designed to work inside programs.

Usage:

import sys
sys.exit()

Execution Time (of just the import and sys.exit()): 0.07s

Or you can use a message for the SystemExit exception:

Added finally block to illustrate code cleanup clause. Inspired by @Nairum.

import sys
try:
  sys.exit("This is an exit!")
except SystemExit as error:
  print(error)
finally:
  print("Preforming cleanup in 3, 2, 1..")
  # Do code cleanup on exit

Output:

This is an exit!

Preforming cleanup in 3, 2, 1..

Pros:

  • Triggers SystemExit exception
  • You can use an exception message
  • Closes without a dialog
  • Utilizes finally clause of try
  • Works both with python 2.x and python 3.x

Cons:

  • Needs an import
  • Slower by 57.1% than exit()

Conclusion:

If you don't need an exception with an optional message, then use exit(), this is faster and built-in. If you require more functionality of an exception with an optional message, use sys.exit().

In the code examples I am using Python 3.x

6 Comments

I write something strange. Cleanup actions specified by finally clauses of try statements are honored by exit() docs.python.org/3/library/sys.html#sys.exit
Thank you, @Nairum. I have added an example to your reference to the answer.
This answer is wrong on so many levels. First of all, exit() also raises SystemExit. Second, your performance comparison is unfair. You should not include the import time unless you never use the sys module anywhere else in your code, which is unlikely (other modules may import it too). Without considering the import time, the performance is reversed. Also, as @miku's answer says, you should not use exit() in scripts just because it's shorter, it's only meant to be used in the REPL. For more details: gist.github.com/nyuszika7h/f2a5962995ed1adb403d7d27b3e7950e
Pray, why would the "performance" of exit() (or sys.exit()) matter? You are exiting anyway... and if that takes 0.03s or 0.06s, who cares? It is not as if you were using exit() repeatedly in a loop :-) In general, Knuth's dictum "Early optimisation is the root of all evil" applies.
@AndrásAszódi While your point about exit performance is true in many (most?) cases, and that was my first reaction to seeing this apparently silly comparison, there is indeed one case where it matters: command line programs. While Python is a poor choice for such applications in the first place, the startup and shutdown time of a CLI app matters because it's entirely possible that they will get called in a shell script loop or in some other context where latency matters (like a status-line plugin). Food for thought! That said, the other points made above still apply...
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.