5 ms·
Hm... Idiom #186 Exit program cleanly for Python: import sys sys.exit(0) Well, I guess I've been reinventing the wheel for my whole career... and thank go
by tomp 7y ago
Hm... Idiom #186 Exit program cleanly for Python:
import sys
sys.exit(0)
Well, I guess I've been reinventing the wheel for my whole career... and thank god I did, my wheel is not only more performant, but also shorter and produces cleaner code (in my subjective opinion). As simple as:
# nothing
- lkbm 7y agoYour solution only works if it's the end of the program. Sometimes you need to exit conditionally. if foo: exit(0) more_code()
- tomp 7y agoIMO that's anti-pattern / code smell, in most situations.
- ainiriand 7y agoYou are right, as for example the tests would behave in an erratic way. It should be allowed to complete.
- aepiepaey 7y agoAs long as we're talking about libraries, yes. For cli tools, on the other hand, there are definitely legitimate cases for exiting early.
- tomp 7y agoSure, but even in most of those scenarios, I’d prefer to structure the code differently... perhaps write a main() function that just returns, or other functions... more modular, maintainable, teatable, ... admittedly, in Python you need to use os.exit if you want to return a specific non-zero exit code, but even in that case good code style would be something like def main() blablabla if foo: return bar ... return 8 if __name__ == “__main__”: os.exit(main()) Of course that’s just my advice / opinion / preference, other ways are valid as well...
- aepiepaey 7y agoAnd in that case, raise SystemExit(code) is nicer (and does not require an an import).
- capableweb 7y agoIsn't raise for "throwing" exceptions/errors though? `raise SystemExit(code)` would imply an error, but if `code` is 0, the OS wouldn't consider it an error but an human looking at it would (correctly?) assume it's a error.
- ORioN63 7y agoTIL SystemExit and that `sys.exit` actually raises SystemExit. From Python docs: https://docs.python.org/3/library/exceptions.html#SystemExit https://docs.python.org/3/library/exceptions.html#SystemExit > exception SystemExit > This exception is raised by the sys.exit() function. It inherits from BaseException instead of Exception so that it is not accidentally caught by code that catches Exception. This allows the exception to properly propagate up and cause the interpreter to exit. When it is not handled, the Python interpreter exits; no stack traceback is printed. The constructor accepts the same optional argument passed to sys.exit(). If the value is an integer, it specifies the system exit status (passed to C’s exit() function); if it is None, the exit status is zero; if it has another type (such as a string), the object’s value is printed and the exit status is one. > A call to sys.exit() is translated into an exception so that clean-up handlers (finally clauses of try statements) can be executed, and so that a debugger can execute a script without running the risk of losing control. The os._exit() function can be used if it is absolutely positively necessary to exit immediately (for example, in the child process after a call to os.fork()). Replying to your comment regarding: > Isn't raise for "throwing" exceptions/errors though? Well, some would argue that is idiomatic in python. A quick google search not only autocompletes "exceptions for control flow" to "exceptions for control flow python", but on the second search, most results discuss that (with many agreeing). I guess you can say most python developer wouldn't immediately assume it's an error. I definitely can say, I don't.
- hathawsh 7y ago
- Sean1708 7y agoYou could literally say that for all the examples, even in C you can omit the return value of main.
- marshray 7y agoI would expect sys.exit() to be more efficient since it skips the final GC and calls to finalizers. Sys is always already imported, so 'import sys' amounts to a dict lookup. These are not the same semantically. It may or may not be practical for you to prove that your program is still correct if finalizers are skipped.