Python script complete exit - python

I'm currently using quit() to end my program but the command line still persists after the execution has finished. How do I "kill" the program?
def ed():
quit()
timer = threading.Timer(time, ed)
timer.start()
The pointer stays active and acts like the script is running.

This could work:
import os
def ed():
os._exit(1)

You can use standard function of Python exit() which can print whatever before exiting and exit from program.
print("start")
exit() # exiting from program
print("end")
start
or
print("start")
exit("exiting") # exiting with output
print("end")
start
exiting

Related

How to exit a while loop only after the current loop has completed in Python?

I'm trying to set up my Python script to allow the user to end the program, however the program needs to finish what it's doing first. I have the following code set up:
import sys
import keyboard
import time
prepareToStop = 0;
try:
while prepareToStop == 0:
#Program code here
print(prepareToStop)
time.sleep(0.1)
except KeyboardInterrupt:
prepareToStop = 1
print("\nProgram will shut down after current operation is complete.\n")
print("Program shutting down...")
sys.exit()
However, the program still exits the loop as soon as the KeyboardInterrupt is received. I've seen advice that this could be fixed by placing the 'try, except' inside the while loop, however this causes the program to fail to detect the KeyboardInterrupt at all.
If I understand your problem correctly, maybe threading can help you. Note how end do something appears even after KeyboardInterrupt.
EDIT : I placed t.join() in the try
import sys
import time
import threading
def do_something(prepareToStop):
print(prepareToStop)
time.sleep(1)
print('end do something')
prepareToStop = 0
while prepareToStop == 0:
t = threading.Thread(target=do_something, args=[prepareToStop])
try:
t.start()
t.join() # wait for the threading task to end
except KeyboardInterrupt:
prepareToStop = 1
print("\nProgram will shut down after current operation is complete.\n")
print('will not appear for last run')
print("Program shutting down...")
sys.exit()
Example of output :
0
end do something
will not appear for last run
0
^C
Program will shut down after current operation is complete.
will not appear for last run
Program shutting down...
end do something
The keyboard interrupt that you were trying to use works like any system interrupt and will jump immediately to the exception block, without going back to where it was when the interrupt has occurred.
You can confirm this by using the debugger in your IDE (ie. Press F5 in VSCODE).
The code below works like you want, but the user has to hold ESC key pressed in the keyboard for it to be captured from the program in the proper time.
import sys
import keyboard
import time
prepareToStop = 0;
while prepareToStop == 0:
if keyboard.is_pressed('Esc'):
prepareToStop = 1
print("\nProgram will shut down after current operation is complete.\n")
#Program code here
print('Sleeping 5 sec - hold the ESC key for some time to exit')
time.sleep(5)
print('This prints only after the delay')
#end code here
print(prepareToStop)
time.sleep(0.1)
print("Program shutting down...")
sys.exit()
And then I would recommend to change into this:
import sys
import keyboard
import time
while not keyboard.is_pressed('Esc'):
#Program code here
print('Sleeping 5 sec - hold the ESC key for some time to exit')
time.sleep(5)
print('This prints only after the delay')
#end code here
time.sleep(0.1)
print("Program shutting down...")
sys.exit()
The above solution is not better than using threading, but it is much more simpler.

Stopping the execution of Python script

I have written this question after reading this question and this other one.
I would like to stop the execution of a Python script when a button is pressed. Here the code:
import turtle
from sys import exit
def stop_program():
print("exit function")
exit(0) #raise SystemExit(0) gives the same result
print("after the exit function")
# Create keyboard binding
turtle.listen()
turtle.onkey(stop_program, "q")
# Main function
while True:
# Code: everything you want
If I press the button "q" (even muliple time) the output is:
exit function
exit function
exit function
exit function
exit function
exit function
exit function
...
i.e. one line every time I press.
This means that the exit works for the function and not for the whole program. Any suggestion?
Dont use the while loop, use turtle.mainloop()
import turtle
from sys import exit
def stop_program():
print("exit function")
exit(0) #raise SystemExit(0) gives the same result
print("after the exit function")
# Create keyboard binding
turtle.listen()
turtle.onkey(stop_program, "q")
turtle.mainloop()
That seems to work fine for me, give it a try.
Try to use: sys.exit(), see if that works. Below code worked for me.
import turtle
import sys
def stop_program():
print("exit function")
sys.exit() #raise SystemExit(0) gives the same result
print("after the exit function")
# Create keyboard binding
turtle.listen()
turtle.onkey(stop_program, "q")
turtle.mainloop()

Terminate background python script nicely

I am running a python script in the background using the command python script.py &. The script might look like this.
import time
def loop():
while True:
time.sleep(1)
if __name__=='__main__':
try:
loop()
except KeyboardInterrupt:
print("Terminated properly")
When it comes to terminating the script, I would like to do some cleanup before it is stopped (such as printing "Terminated properly"). If I run as a current process, this would be handled by the except statement after a keyboard interrupt.
Using the kill PID command means the cleanup is never executed. How can I stop a background process and execute some lines of code before it is terminated?
You can use signal module to catch any signals sent to your script via kill.
You setup a signal handler to catch the signal in question that would perform the cleanup.
import signal
import time
running = 0
def loop ():
global running
running = 1
while running:
try: time.sleep(0.25)
except KeyboardInterrupt: break
print "Ended nicely!"
def cleanup (signumber, stackframe):
global running
running = 0
signal.signal(signal.SIGABRT, cleanup)
signal.signal(signal.SIGTERM, cleanup)
signal.signal(signal.SIGQUIT, cleanup)
loop()
Use finally clause:
def loop():
while True:
time.sleep(1)
if __name__=='__main__':
try:
loop()
except KeyboardInterrupt:
print("Terminated properly")
finally:
print('executes always')

Make Exe Continue Till A Thread Has Completed

I am compiling my Python script into a Windows Executable. The script simply downloads a a files and saves them locally - each download uses a different thread. I am finding that my simple application exits before any of the threads finish. But I am not entirely sure?
Does my script below exit before the threads finish or does the script wait till they are done? AND If the script does exit before the threads finish - How can I stop this?
Whats they standard practice to avoid this? Should I use a while loop that checks if any threads are still alive or is there a standard way of doing this?
import thread
import threading
import urllib2
def download_file():
response = urllib2.urlopen("http://website.com/file.f")
print "Res: " + str(response.read())
raw_input("Press any key to exit...")
def main():
# create thread and run
#thread.start_new_thread (run_thread, tuple())
t = threading.Thread(target=download_file)
t.start()
if __name__ == "__main__":
main()
# The below prints before "Res: ..." which makes me think the script exits before the thread has completed
print("script exit")
What you are looking for is the join() function on your newly created thread, which will block the execution of code until the thread is done. I took the liberty of removing your def main() as it is completely not needed here and only creates confusion.
If you want to wrap the launch of all downloads into a neat function, then pick a descriptive name for it.
import thread
import threading
import urllib2
def download_file():
response = urllib2.urlopen("http://website.com/file.f")
print "Res: " + str(response.read())
raw_input("Press any key to exit...")
if __name__ == "__main__":
t = threading.Thread(target=download_file)
t.start()
t.join()
# The below prints before "Res: ..." which makes me think the script exits before the thread has completed
print("script exit")

python thread weird behavior

I have a timer function which I am calling it in another function like this
import time
import threading
def f():
while(True):
print "hello"
time.sleep(5)
def execute():
t = threading.Timer(5,f)
t.start()
command = ''
while command != 'exit':
command = raw_input()
if command == 'exit':
t.cancel()
Even if after entering "exit" command, the function is printing "hello"
I am not able to figure out Whats wrong with the code
class threading.Timer - cancel() - Doc-Link
Stop the timer, and cancel the execution of the timer’s action. This will only work if the timer is still in its waiting stage.
A very simple Version of what you are trying to accomplish could look like this.
import threading
_f_got_killed = threading.Event()
def f():
while(True):
print "hello"
_f_got_killed.wait(5)
if _f_got_killed.is_set():
break
def execute():
t = threading.Timer(5,f)
t.start()
command = ''
while command != 'exit':
command = raw_input()
if command == 'exit':
_f_got_killed.set()
t.cancel()
execute()
For forcefully killing a thread look at this:
Is there any way to kill a Thread in Python?
You are using cancel wrong. In http://docs.python.org/2/library/threading.html, it states: "Timers are started, as with threads, by calling their start() method. The timer can be stopped (before its action has begun) by calling the cancel() method. The interval the timer will wait before executing its action may not be exactly the same as the interval specified by the user."
In your code, if you try to use cancel after the timed thread has already begun its execution (it will in 5 seconds), cancel accomplishes nothing. The thread will remain in the while loop in f forever until you give it some sort of forced interrupt. So typing "exit" in the first 5 seconds after you run execute works. It will successfully stop the timer before the thread even begins. But after your timer stops and your thread starts executing the code in f, there will be no way to stop it through cancel.

Categories

Resources