On 14 Feb, 14:27, Michael Goerz <[EMAIL PROTECTED]> wrote: > Hi, > > I'm writing a command line program that watches a file, and recompiles > it when it changes. However, there should also be a possibility of doing > a complete clean restart (cleaning up temp files, compiling some > dependencies, etc.). > > Since the program is in an infinite loop, there are limited means of > interacting with it. Right now, I'm using the Keyboard Interrupt: if the > user presses CTRL+C once, a clean restart is done, if he presses it > twice within a second, the program terminates. The stripped down code > looks like this: > > while True: > try: > time.sleep(1) > if watched_file_has_changed(): > compile_the_changed_file() > except KeyboardInterrupt: # user hits CTRL+C > try: > print("Hit Ctrl+C again to quit") > time.sleep(1) > clean_restart() > except KeyboardInterrupt: > do_some_cleanup() > sys.exit(0) > > Is there another way of doing this? Ideally, there would be an exception > every time any key at all is pressed while the code in the try block is > being executed. That way, the user could just hit the 'R' key to do a > clean restart, and the 'E' key to exit the program. Is there any way to > implement something like that? > > Right now, the CTRL+C solution works, but isn't very extensible (It > wouldn't be easy to add another command, for example). Any suggestions? > > Thanks, > Michael
I don't know any way to extend your solution. However, I would suggest to experiment with the threading module. Threading in Python is quite easy, as long as that you stick with queue and events for communications between threads. Here is an example, where the main thread is used to handle the console and the background thread does the job. The assumption is that the background thread can do the job in separate short steps, checking for new commands between steps. This esemple uses events to signal commands to the background thread and uses a queue to send from background thread to main thread synchronous messages to be displayed on the console. I guess the example could be shorter if I used a command queue instead of events, but I wanted to show how to use events. The program works, but surely can be improved ... Ciao -------- FB # # Example of program with two threads # one of MMI, one background # import sys, traceback import threading, time, Queue class BackgroundThread(threading.Thread): TICK = 1.0 def __init__(self, msg_queue): threading.Thread.__init__(self) self.reset_event = threading.Event() self.quit_event = threading.Event() self.msg_queue = msg_queue def do_job(self): pass # This shoud execute each time a step and return shortly def do_reset(self): pass def run(self): while not self.quit_event.isSet(): self.do_job() # should be one short step only time.sleep(self.TICK) if self.reset_event.isSet(): self.do_reset() self.reset_event.clear() self.msg_queue.put('Reset completed') def main(): msg_queue = Queue.Queue() print 'Starting background thread ...' b_thread = BackgroundThread(msg_queue) b_thread.start() while 1: print 'Type R to reset' print 'Type Q to quit' cmd = raw_input('Command=>') if cmd in 'Rr': b_thread.reset_event.set() # wait for reset command completion print msg_queue.get() elif cmd in 'qQ': b_thread.quit_event.set() break print 'Waiting the background thread to terminate ...' b_thread.join() print 'All done.' if __name__ == '__main__': try: main() print 'Program completed normally.' raw_input('Type something to quit') except: err, detail, tb = sys.exc_info() print err, detail traceback.print_tb(tb) raw_input('Oops...') -- http://mail.python.org/mailman/listinfo/python-list