How to catch signal and pass a variable when exit in Python?

Viewed 1582

I am trying to catch a signal and pass a variable to an exit handler.

The Python3 signal handling signal.signal(signal.SIGINT, exit_handler), which I use now, cannot pass a variable.

Here is my code:

import signal

def main(driver):
  ""
  # somecode

def exit_handler(sig, frame):
    driver.quit()
    db.update
    # etc
    exit()

if __name__ == '__main__':
    driver = ""
    database = ""
    signal.signal(signal.SIGINT, exit_handler) # pass variable to exit_handler
    exit()

How to accomplish that?

2 Answers

Handler needs to be a callable object that takes two arguments (signal number and the current stack frame) when called. You can write your own object and make it callable by defining __call__ method and whose constructor takes one or more arguments you can keep around to use when it's later being invoked. For instance:

import signal
import time

def main():
    while True:
        time.sleep(1)

class MyHandler:
    def __init__(self, myvar):
        self.myattr = myvar
    def __call__(self, signo, frame):
        print("My variable was:", self.myattr)

if __name__ == '__main__':
    signal.signal(signal.SIGINT, MyHandler(123))
    main()

If needed values stored within the handler instance could also be updated during lifetime of the script and then used when it gets called.

Another option is to use a lambda function, and pass the variables in the closure:

import signal
import time

def handler(signum, frame, arg1, arg2):
  print(arg1)
  print(arg2)
  exit(1)

signal.signal(signal.SIGINT, lambda signum, frame: handler(signum, frame, 'foo', 'bar'))

while True:
  time.sleep(1)
Related