Как поймать сигнал и передать переменную при выходе в python?

Я пытаюсь поймать сигнал и передать переменную обработчику выхода.

Обработчик сигнала Python3 signal.signal(signal.SIGINT, exit_handler), который я использую сейчас, не может передавать переменную.

Вот мой код:

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()

Как этого добиться?

В чем вопрос? Кроме того, напишите фрагмент кода, который может быть выполнен другими пользователями. документыsignal.signal указывает, что функция принимает два аргумента, (signalnum, handler), и ничего более

Daneel R. 13.09.2018 20:30

@DanielR. я знаю, но как передать аргумент функции exit_handler

user10359693 14.09.2018 05:49

Я бы использовал глобальные переменные, создав / назначив им непосредственно перед вызовом signal.signal, а затем используя их в exit_handler. В противном случае вам придется искать другую библиотеку, signal.signal не позволяет передавать аргументы обработчику.

Daneel R. 14.09.2018 09:29
2
3
955
2

Ответы 2

Обработчик должен быть вызываемым объектом, который при вызове принимает два аргумента (номер сигнала и текущий кадр стека). Вы можете написать свой собственный объект и сделать его вызываемым, определив метод __call__, конструктор которого принимает один или несколько аргументов, которые вы можете использовать при последующем вызове. Например:

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()

При необходимости значения, хранящиеся в экземпляре обработчика, также могут быть обновлены в течение времени существования скрипта, а затем использованы при его вызове.

Другой вариант - использовать лямбда-функцию и передать переменные в закрытии:

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)

Другие вопросы по теме