Domanda

I have a program that needs to stop processing altogether once a certain condition has been triggered - similar to this question: How do I abort the execution of a Python script?

However, in my case, I want to capture the traceback that sys.exit() generates AND MOST IMPORTANTLY stop processing anything code blocks beyond that point. Can anyone help with this?

try:
    a = 'i' / 1
    print 'Does this work yet?'
except TypeError:
    print "I should stop processing now"
    try:
        sys.exit()
    except:
        pass
print 'I did not stop processing '
È stato utile?

Soluzione

I'm not entirely sure what you are asking, as far as I know sys.exit() does not generate a traceback. If you try to execute your code as it is, sys.exit() raises an unhandled NameError exception because you have not imported the "sys" module. Surrounding the call to sys.exit() with a try/except block will capture the NameError exception, but it will also capture the normal exception raised by sys.exit(), as per the documentation:

Exit from Python. This is implemented by raising the SystemExit exception, so cleanup actions specified by finally clauses of try statements are honored, and it is possible to intercept the exit attempt at an outer level.

Here is a version that stops processing once it encounters an error.

import sys

try:
    a = 'i' / 1
    print 'Does this work yet?'
except TypeError:
    print "I should stop processing now"
    sys.exit()
print 'I did not stop processing '

If this code is in your main module, I suggest wrapping your entry-point code up like this:

import sys

def main():
    try:
        a = 'i' / 1
        print 'Does this work yet?'
    except TypeError:
        print "I should stop processing now"
        return 1
    print 'I did not stop processing '
    return 0

if __name__ == "__main__": sys.exit(main())

This way you only ever have one call to sys.exit(), and it returns an error code indicating if there was a problem. If your code is not in the top-level entry point, I suggest you just throw the exception up until it gets to the main() method, where it can then return the error code value. You can wrap the real exception in a new "StopMyApplicationException" that you have to define.

Oh, and if you want to print the traceback, you can use the traceback module, something like traceback.print_exc() will do the job.

Altri suggerimenti

You can use the fact that system-exiting exceptions don't derive from Exception:

try:
    a = 'i' / 1
    print 'Does this work yet?'
except TypeError:
    print "I should stop processing now"
    try:
        raise SystemExit
    except Exception:
        pass

You can get access to the exception that sys.exit generates, but it will have no traceback.

try:
    sys.exit()
except SystemExit as e:
    # do what you want with e, e.g.
    traceback.print_exc(e)
    raise

A bare raise in an except clause re-raises the caught exception.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top