Выполнение действия при неожиданном выходе python
Я блуждал, если был способ выполнить действие до закрытия программы. Я запускаю программу в течение долгого времени, и я хочу, чтобы ее можно было закрыть и сохранить данные в текстовом файле или что-то в этом роде, но мне не мешает вмешаться в while True
время, while True
loop, и просто сохраняя данные, каждый цикл будет крайне неэффективным.
Итак, есть ли способ сохранить данные, скажем, список, когда я ударил x
или уничтожу программу? Я смотрел на модуль atexit, но мне не повезло, если только я не запустил программу в определенный момент.
- запросы python в Google App Engine не работают для HTTPS
- Случайное генерирование математических вопросов
- ForbiddenError при попытке записать файл в GCS из приложения GAE python
- если инструкция Else внутри цикла не работает
- Python SyntaxError: ("'return' с аргументом внутри генератора",)
def saveFile(list): print "Saving List" with open("file.txt", "a") as test_file: test_file.write(str(list[-1])) atexit.register(saveFile(list))
Это моя целая часть кода и, как я уже сказал, она отлично работает, когда я устанавливаю ее для закрытия while loop
.
Возможно ли это, чтобы сохранить что-то, когда приложение прекращено?
4 Solutions collect form web for “Выполнение действия при неожиданном выходе python”
Ваше использование atexit
неверно. Он ожидает функцию и ее аргументы, но вы сразу вызываете свою функцию и передаете результат atexit.register()
. Пытаться:
atexit.register(saveFile, list)
Имейте в виду, что это использует ссылку на list
как она существует во время вызова atexit.register()
, поэтому, если вы назначите list
позже, эти изменения не будут подняты. Однако изменение самого списка без переназначения должно быть прекрасным.
Вы можете использовать менеджер контекста handle_exit
из этого рецепта ActiveState:
http://code.activestate.com/recipes/577997-handle-exit-context-manager/
Он обрабатывает SystemExit
, KeyboardInterrupt
, SIGINT
и SIGTERM
, с простым интерфейсом:
def cleanup(): print 'do some cleanup here' def main(): print 'do something' if __name__ == '__main__': with handle_exit(cleanup): main()
Вы ничего не можете SIGKILL
на SIGKILL
. Он убивает ваш процесс немедленно, без какой-либо разрешенной очистки.
Поймайте исключение SystemExit
в верхней части приложения, а затем снимите его.
Есть несколько подходов к этому. Как некоторые комментируют, вы могли использовать обработку сигналов … ваш [Ctrl] + [C] из терминала, на котором он работает на переднем плане, отправляет сигнал SIGHUP вашему процессу (из драйверов терминала).
Другим подходом было бы использовать неблокирующий os.read()
на sys.stdin.fileno
, чтобы вы проводили опрос своей клавиатуры один в течение каждого цикла, чтобы узнать, было ли введено «выход» нажатие клавиши или последовательность.
Подобный подход неблокирующего опроса может быть реализован с использованием функциональности модуля select
. Я вижу, что используется с termios
и модулями tty
. (Кажется неэлегантным, что ему нужны все те, которые нужно сохранить, установить изменения и восстановить параметры терминала, а также я увидел некоторые примеры с помощью os
и fcntl
, и я не уверен, когда и почему вы предпочтете один из них если os.isatty(sys.stdin.fileno())
).
Еще одним подходом было бы использовать модуль curses
с window.nodelay()
или window.timeout()
чтобы установить желаемое поведение ввода, а затем либо window.getch()
либо window.getkey()
для опроса для любого ввода.