klappnase wrote:
...
IDLE 1.0
Traceback (most recent call last):
File "<pyshell#1>", line 1, in -toplevel-
sys.exit(23)
SystemExit: 23
As you see, with the IDLE 1.0 which comes with Python 2.3, the
exception raised by sys.exit is captured and displayed as such
[and similarly if sys.exit is called from a module run within
the IDLE session, rather than directly at the IDLE prompt].
Oh, that is interesting, my IDLE (python-2.2.2) exits on this.
One of the several good reasons to upgrade to 2.3, yes.
Does this happen with sys.exit(0) too?
Sure.
Often one may want to do some kind of clean-up at that point, but you
may achieve that with a try/finally around the mainloop call (putting
the cleanup code in the finally clause, of course).
Seems like you mean something like:
def quitcmd():
mainwindow.quit()
do_this()
do_that()
Nope. There's no reason to have to bundle the cleanup as sub-functions
inside another function and so on. Rather, the concept is that cleanup
is generally best done at the same level in which (e.g.) a resource is
acquired. The try/finally-free approach would be structured like:
channel = channels_library.open_channel('blah', 'blah')
# here: set up the GUI; then:
mainwindow.mainloop() # start and run the GUI
# when the GUI is done (and exits with quit) we can do our cleanup
channel.flush_any_unsent_data() # initiate lenghty flush operation
channel.wait_up_to(10.0) # may take up to 10 seconds' wait here
channel.final_close() # and then we finally give up
This only works if the mainloop exits without exiting the whole
Python session, of course. If you want to ensure the flushing &c
happen in any case, including uncaught exceptions, then a more
solid structure, as I mentioned, is try/finally:
try:
mainwindow.mainloop()
finally:
channel.flush... &c &c
If this is what you meant, what is the problem with:
def exitcmd():
do_this()
do_that()
sys.exit(0)
Hard to say without knowing what do_this and do_that do, but in
general (unless you have full control on them and can guarantee
they're done very VERY fast) this is a disaster -- the GUI freezes
(for up to 10 seconds, or a minute, or... who can tell?) while
the program performs its potentially-lengthy cleanup operations.
When you do background clean-up operations AFTER terminating the
GUI, this is generally quite preferable. A clean-up operation
can be considered a "background" one if you're not going to give
the user feedback about what happens in it (you may e.g. log info
to a logfile, but aren't going to popup a message box or the like).
Of course, this doesn't matter if all cleanup operations can be
guaranteed to terminate within, say, a couple of seconds, but
e.g. when the ner is involved, that is quite rarely true.
Since there are no advantages in doing background clean-up while
still not closing the GUI, but there may be disadvantages, it
is best to choose the approach that never gives problems -- do
the background clean-up after closing the GUI.
I do not think that there is much difference in the behavior of these.
You may not have thought the issue through, then; for example, you
may never have needed to perform length background clean-ups.
May be if I launched the application from a menu and the do_that()
function does something really stupid that causes an endless loop, I
think with quitcmd() it might occur that the window is closed and I
think "Fine, the application is shut down" but the buggy do_that() is
still running in the background. With exitcmd() this won't happen, the
window will not close before do_that() comes to an end, so I will see
that there is something wrong.
But taking many seconds to finish handshaking with communication
partners, and other such background clean-up operations, does not
mean "there is something wrong" -- such delays can be perfectly
normal, yet there is no reason to keep the user staring at a frozen
GUI while the delays go on.
Alex