I'm rather new to python and I'm stuck with the following problem. I have a script that processes files one-by-one and writes output into separate files according to input file name. Sometimes I need to break the script, but I'd like to let it finish processing current file and then terminate (to avoid result files with incomplete information). How to code this behavior in python?
Here is what I tried.
a) Try-except block
x = 1
print "Script started."
while True:
try:
print "Processing file #",x,"started...",
# do something 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 is not finished gracefully.
b) sys.excepthook
OriginalExceptHook = sys.excepthook
def NewExceptHook(type, value, traceback):
global Terminator
Terminator = True
if type == KeyboardInterrupt:
#exit("\nExiting by CTRL+C.") # this line was here originally
print("\n\nExiting by 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...",
# do something time-cosnuming
time.sleep(1)
x += 1
print " finished."
if Terminator:
print "I'll be 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 by CTRL+C.
Iteration #3 is not finished gracefully.
UPD#1
@mguijarr , I slightly modified code like this:
import time, sys
x = 1
print "Script started."
stored_exception=None
while True:
try:
print "Processing file #",x,"started...",
# do something 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 is (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 this case iteration #3 was effectively restarted, which looks odd and is not a desired behavior. Is it possible to avoid this?
I removed commas in 'print' statements and added more stuff to see that iteration is actually 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
# do something 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 the 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