How to terminate loop gracefully when CTRL+C was pressed in python -


i'm rather new python , i'm stuck following problem. have script processes files one-by-one , writes output separate files according input file name. need break script, i'd let finish processing current file , terminate (to avoid result files incomplete information). how code behavior in python?

here tried.

a) try-except block

x = 1 print "script started." while true:  try:   print "processing file #",x,"started...",   # time-cosnuming   time.sleep(1)   x += 1   print " finished."  except keyboardinterrupt:   print "bye"   print "x=",x   sys.exit()  sys.exit() 

output:

script started. processing file # 1 started...  finished. processing file # 2 started...  finished. processing file # 3 started... bye x= 3 

iteration #3 not finished gracefully.

b) sys.excepthook

originalexcepthook = sys.excepthook def newexcepthook(type, value, traceback): global terminator     terminator = true     if type == keyboardinterrupt:         #exit("\nexiting ctrl+c.")   # line here         print("\n\nexiting ctrl+c.\n\n")     else:         originalexcepthook(type, value, traceback) sys.excepthook = newexcepthook  global terminator terminator = false  x = 1 while true:   print "processing file #",x,"started...",   # time-cosnuming   time.sleep(1)   x += 1   print " finished."   if terminator:    print "i'll back!"    break  print "bye" print "x=",x sys.exit() 

output:

script started. processing file # 1 started...  finished. processing file # 2 started...  finished. processing file # 3 started...  exiting ctrl+c. 

iteration #3 not finished gracefully.

upd#1

@mguijarr , modified code this:

import time, sys  x = 1 print "script started." stored_exception=none  while true:     try:         print "processing file #",x,"started...",         # time-cosnuming         time.sleep(1)         print "processing file #",x,"part two...",         time.sleep(1)         print " finished."         if stored_exception:             break         x += 1     except keyboardinterrupt:         print "[ctrl+c detected]",         stored_exception=sys.exc_info()  print "bye" print "x=",x  if stored_exception:     raise stored_exception[0], stored_exception[1], stored_exception[2]  sys.exit() 

the output (tested using "python 2.7.6 :: anaconda 2.0.0 (64-bit)" on win7-64bit):

script started. processing file # 1 started... processing file # 1 part two...  finished. processing file # 2 started... processing file # 2 part two...  finished. processing file # 3 started... [ctrl+c detected] processing file # 3 started... processing file # 3 part two...  finished. bye x= 3 traceback (most recent call last):   file "test2.py", line 12, in <module>     time.sleep(1) keyboardinterrupt 

in case iteration #3 restarted, looks odd , not desired behavior. possible avoid this?

i removed commas in 'print' statements , added more stuff see iteration restarted:

import time, sys  x = 1 y = 0 print "script started." stored_exception=none  while true:     try:         y=x*1000         y+=1         print "processing file #",x,y,"started..."         y+=1         # time-cosnuming         y+=1         time.sleep(1)         y+=1         print "processing file #",x,y,"part two..."         y+=1         time.sleep(1)         y+=1         print " finished.",x,y         y+=1         if stored_exception:             break         y+=1         x += 1         y+=1     except keyboardinterrupt:         print "[ctrl+c detected]",         stored_exception=sys.exc_info()  print "bye" print "x=",x print "y=",y  if stored_exception:     raise stored_exception[0], stored_exception[1], stored_exception[2]  sys.exit() 

and output is:

script started. processing file # 1 1001 started... processing file # 1 1004 part two...  finished. 1 1006 processing file # 2 2001 started... processing file # 2 2004 part two... [ctrl+c detected] processing file # 2 2001 started... processing file # 2 2004 part two...  finished. 2 2006 bye x= 2 y= 2007 traceback (most recent call last):   file "test2.py", line 20, in <module>     time.sleep(1) keyboardinterrupt 

i use exception handler, catch keyboardinterrupt , store exception. then, @ moment iteration finished, if exception pending break loop , re-raise exception (to let normal exception handling chance happen).

this works (tested python 2.7):

x = 1 print "script started." stored_exception=none  while true:     try:         print "processing file #",x,"started...",         # time-cosnuming         time.sleep(1)         print " finished."         if stored_exception:             break         x += 1     except keyboardinterrupt:         stored_exception=sys.exc_info()  print "bye" print "x=",x  if stored_exception:     raise stored_exception[0], stored_exception[1], stored_exception[2]  sys.exit() 

edit: has been spotted in comments, answer not satisfying original poster, here solution based on threads:

import time import sys import threading  print "script started."  class myprocessingthread(threading.thread):     def __init__(self):         threading.thread.__init__(self)      def run(self):         print "processing file #",x,"started...",         # time-cosnuming         time.sleep(1)         print " finished."  x in range(1,4):     task = myprocessingthread()     task.start()     try:         task.join()     except keyboardinterrupt:         break  print "bye" print "x=",x  sys.exit() 

Comments

Popular posts from this blog

google api - Incomplete response from Gmail API threads.list -

Installing Android SQLite Asset Helper -

Qt Creator - Searching files with Locator including folder -