mortuzahasan
mortuzahasan

Reputation: 53

Python - KeyboardInterrupt or RuntimeError implementation

New to python and programming. I have a program consist of several classes, module and functions. the program runs from a main class which calls several modules and function

My question is how to implement keyboardinterrupt if the user wants to terminate a running program at any point. Do I need to implement 'try/except' method in all the functions? or this can be implementable in the main function?

To catch interrupt at any moment do I need to use try/except in all the calling functions?

def KEYBOARD_INTERRUPT():
while True:
    yesnoinput=raw_input('Do you want to exit from software [Y/N]:') 
        if yesnoinput=='y' or yesnoinput.upper()=='Y':
            sys.exit()
        elif yesnoinput=='n' or yesnoinput.upper()=='N':
            break
        else:
            continue
def A():
    while True:
        try:
            userInput=raw_input("Please enter A")
            if userInput=='A':
                break
            else:
                continue
        except KeyboardInterrupt:
            KEYBOARD_INTERRUPT()

def B():

      userInput=raw_input("Please enter B")
      if userInput=='B':
            break
      else:
            continue

def main():
    try:
        A()
        B()
    except:
        KEYBOARD_INTERRUPT()

when main program is calling function B, at this moment if the user presses keyboardInterrupt the program will quit with error messgage, I am worried if I want to handle interrupt like KEYBOARD_INTERRUPT function I need to implement this in very function such as function A?

Did I understand wrong?

Upvotes: 0

Views: 2153

Answers (2)

tdelaney
tdelaney

Reputation: 77337

Exceptions flow up the stack, terminating each function execution block as it goes. If all you want is a nice message, catch it at the top, in your main. This script has two mains - one that catches, one that doesnt. As you can see, the non-catcher shows a stack trace of where each function broke execution but its kinda ugly. The catcher masks all that - although it could still write the info to a log file if it wanted to.

import sys
import time

def do_all_the_things():
    thing1()

def thing1():
    thing2()

def thing2():
    time.sleep(120)

def main_without_handler():
    do_all_the_things()

def main_with_handler():
    try:
        do_all_the_things()
    except KeyboardInterrupt:
        sys.stderr.write("Program terminated by user\n")
        exit(2)

if __name__ == "__main__":
    # any param means catch the exception
    if len(sys.argv) == 1:
        main_without_handler()
    else:
        main_with_handler()

Run it from the console and hit ctrl-c and you get:

td@mintyfresh ~/tmp $ python3 test.py
^CTraceback (most recent call last):
  File "test.py", line 26, in <module>
    main_without_handler()
  File "test.py", line 14, in main_without_handler
    do_all_the_things()
  File "test.py", line 5, in do_all_the_things
    thing1()
  File "test.py", line 8, in thing1
    thing2()
  File "test.py", line 11, in thing2
    time.sleep(120)
KeyboardInterrupt
td@mintyfresh ~/tmp $ 
td@mintyfresh ~/tmp $ 
td@mintyfresh ~/tmp $ python3 test.py handled
^CProgram terminated by user

Upvotes: 1

Claude
Claude

Reputation: 11

You could do something like :

try:
...
   except KeyboardInterrupt: 
       Do something

Upvotes: 0

Related Questions