sys.exit doesn't work as expected after try:

2019-06-10 02:30发布

问题:

I tried the following script.

My original intention is that if the command "command_a" in the following code segment is executed successfully, the program ends. Otherwise, it performs additional processing.

#!/usr/bin/python

import subprocess
try:
  command = "command_a"
  subprocess.check_call(command.split())
  print "Woks fine!, and stopping"
  sys.exit()


except:
  pass

print "Continue additional processing"
call_some_additional_processing()

However, I notice that sys.exit() does not work as expected. Even if subprocess.check_call succeeds, it calls call_some_additional_processing().

Could you please tell me what the reason is, and what would be the best to resolve this problem?

回答1:

sys.exit works by raising the SystemExit exception. Since you have a bare except, your SystemExit exception is getting caught and suppressed.

This is one reason why you should never have bare except clauses. At the very minimum, catch Exception:

try:
    sys.exit()
except Exception:
    pass

Since SystemExit doesn't inherit from Exception1, it won't get caught. As a more general rule, you should never catch an exception if you don't know how to handle it. Even catching Exception is nearly always more broad than you actually want.


Finally, if you ever find yourself in a situation where you're forced to deal with someone else's code and they have a bare except that you can't change, you can use os._exit to terminate the current process without raising SystemExit. This is generally a bad idea and should only be resorted to in the most dire of circumstances however2.

1SystemExit and KeyboardInterrupt inherit from BaseException explicitly so that they won't get caught when someone is catching Exception.
2Hopefully I've made it clear enough that this last paragraph is meant to give information -- It isn't something that I would ever recommend using ;-)