Reading online some programmers use sys.exit
, others use SystemExit
.
Sorry for the basic question:
No practical difference, but there's another difference in your example code - print
goes to standard out, but the exception text goes to standard error (which is probably what you want).
sys.exit(s)
is just shorthand for raise SystemExit(s)
, as described in the former's docstring; try help(sys.exit)
. So, instead of either one of your example programs, you can do
sys.exit('Unable to open %s' % reference)
There are 3 exit functions, in addition to raising SystemExit
.
The underlying one is os._exit
, which requires 1 int argument, and exits immediately with no cleanup. It's unlikely you'll ever want to touch this one, but it is there.
sys.exit
is defined in sysmodule.c and just runs PyErr_SetObject(PyExc_SystemExit, exit_code);
, which is effectively the same as directly raising SystemExit
. In fine detail, raising SystemExit
is probably faster, since sys.exit
requires an LOAD_ATTR
and CALL_FUNCTION
vs RAISE_VARARGS
opcalls. Also, raise SystemExit
produces slightly smaller bytecode (4bytes less), (1 byte extra if you use from sys import exit
since sys.exit
is expected to return None, so includes an extra POP_TOP
).
The last exit function is defined in site.py
, and aliased to exit
or quit
in the REPL. It's actually an instance of the Quitter
class (so it can have a custom __repr__
, so is probably the slowest running. Also, it closes sys.stdin
prior to raising SystemExit
, so it's recommended for use only in the REPL.
As for how SystemExit
is handled, it eventually causes the VM to call os._exit, but before that, it does some cleanup. It also runs atexit._run_exitfuncs()
which runs any callbacks registered via the atexit
module. Calling os._exit
directly bypasses the atexit
step.
SystemExit
is an exception, which basically means that your progam had a behavior such that you want to stop it and raise an error. sys.exit
is the function that you can call to exit from your program, possibily giving a return code to the system.
EDIT: they are indeed the same thing, so the only difference is in the logic behind in your program. An exception is some kind of "unwanted" behaviour, whether a call to a function is, from a programmer point of view, more of a "standard" action.
According to documentation sys.exit(s)
effectively does raise SystemExit(s)
, so it's pretty much the same thing.
My personal preference is that at the very least SystemExit
is raised (or even better - a more meaningful and well documented custom exception) and then caught as close to the "main" function as possible, which can then have a last chance to deem it a valid exit or not. Libraries/deeply embedded functions that have sys.exit
is just plain nasty from a design point of view. (Generally, exiting should be "as high up" as possible)