Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python terminating your program at any time?

Tags:

python

I want to be able to end my program after I run at any point of time. Similar to how I press ctrl + c and it says keyboard interrupt but I don't want something like

if "keyboard press here" == true:
  quit()

the reason I don't want it to be like above is because it seems that my code will run until it reaches this part of my code. Is there a command

edit:

Sorry, if I'm not clear on my question. What I mean is that I don't want my program to have to reach the point of where it says "press keyboard to quit" in my program but to have it in every space. so for example if I have a while loop that looks something like this:

while True
print "1"
print "2"
if "keyboard press here" == true:
      quit()
print "3"
print "4"

I'd have to wait till it prints out

>>>1
>>>2

before it I can press my keyboard to stop or if it passes 2 and goes to print 3 it'd look like this

>>>1
>>>2
>>>3
>>>4
>>>1
>>>2

and then my program will stop.

I'd like to have my program work like this:

while True
    print "1"
    if "keyboard press here" == true:
          quit()
    print "2"
    if "keyboard press here" == true:
          quit()
    print "3"
    if "keyboard press here" == true:
          quit()
    print "4"
    if "keyboard press here" == true:
          quit()

but I don't want to keep putting

if "keyboard press here" == true: quit()

every other space. Is there a way to do that?

like image 842
aWLW Avatar asked Dec 02 '25 17:12

aWLW


2 Answers

Hm, it isn't pretty, but all I can think of is really handling the keyboard interrupts...

while True:
    try:
        # your main code here   
    except KeyboardInterrupt:
        break # or quit(), or sys.exit()

Edit:

To answer your updated question:

What I mean is that I don't want my program to have to reach the point of where it says "press keyboard to quit" in my program but to have it in every space

Well, you don't have to, the try-except does exactly what you want. To apply this code to your updated answer:

while True:
    try:
        print "1"
        print "2"
        print "3"
        print "4"
    except KeyboardInterrupt:
        break

You can create a signal handler, or override with your own excepthook.

Signal Handler

A signal handler may help.

import sys
import signal


def terminate(signal, frame):
    print("received SIGINT, exit..." file=sys.stderr)
    sys.exit(0)

signal.signal(signal.SIGINT, terminate)

for i in range(0, 100000):
    print(i)

But be careful with the signal handler, you should write your signal handler very very carefully. It is really hard to write a correct signal handler even for a experienced UNIX C programmer.

When a program received a signal, it will be paused ungracefully.

For example, print() blocks a stream or IO device while it is working, when a signal generated, it will be paused in order to execute the signal handler. This time, So you can't call (reentrant) print() when current print() does not return yet because it is still holding the stream/device.

Even worse, the signal will be triggered when the current signal handler is still running. So, the signal handler and all the functions must allow reentrant calls.

But it is easier and safer in Python, because Python did all necessary works to allow core functions to reentry.

Exception Hook

Where are trackback errors come from? Python will call a special function (sys.__excepthook__) to print the trackback when there is an unhandled exception.

You could override it and do anything extra (except to raise an unhandled exception to avoid infinite recursion ^_^), and you don't need to think about the reentrant problem.

We often use this feature to write down the error to a logfile or popup a warning window. But it works for your situation.

import sys


def my_excepthook(type, value, traceback):
    if type is KeyboardInterrupt:
        print("got KeyboardInterrupt, exit...")
        sys.exit(0)
    else:
        # call the original hook to print the trackback properly
        sys.__excepthook__(type, value, traceback)

sys.excepthook = my_excepthook

for i in range(0, 100000):
    print(i)

BTW, a warning, these two methods are applicable for multithreading programming, but you need to do more than the examples, and be more careful.

like image 35
比尔盖子 Avatar answered Dec 05 '25 07:12

比尔盖子



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!