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
Post a Comment