Будет ли Python выполнять блок finally после получения Ctrl + C

Если вы остановите скрипт Python с помощью Ctrl + C, он выполнит какие-либо блоки finally или буквально остановит скрипт там, где он находится?


person generic purple turtle    schedule 22.12.2016    source источник
comment
ты не можешь проверить это сам?   -  person Jean-François Fabre    schedule 22.12.2016
comment
Он убивает его там, где он есть   -  person Roman    schedule 22.12.2016
comment
Я не понимаю, что имеет в виду ваш вопрос. Предлагаю вам прочитать: stackoverflow.com/help/how-to-ask и catb.org/~esr/faqs/smart-questions.html   -  person Pitto    schedule 22.12.2016
comment
запустите CTRL + C из MinGW / Windows, он просто убивает процесс, не отправляет прерывание клавиатуры. Но это особый случай.   -  person Jean-François Fabre    schedule 22.12.2016


Ответы (3)


Что ж, ответ в основном зависит от. Вот что происходит на самом деле:

  • Python выполняет код в блоке try:... finally:
  • Ctrl-C испускается и переводится в исключение KeyboardInterrupt Exception
  • обработка прерывается и управление переходит к блоку finally

Так что на первый взгляд все работает как положено. Но...

Когда пользователь (не вы, а другие ...) хочет прервать выполнение задачи, он обычно несколько раз нажимает Ctrl-C. Первый ответит на выполнение в блоке finally. Если другой Ctrl-C встречается в середине блока finally, потому что он содержит медленные операции, такие как закрытие файлов, будет вызван новый KeyboardInterrupt, и ничто не гарантирует, что весь блок будет выполнен, и вы могли бы иметь что-то вроде:

Traceback (most recent call last):
  File "...", line ..., in ...
    ...
KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "...", line ..., in ...
    ...
  File "...", line ..., in ...
    ...
KeyboardInterrupt
person Serge Ballesta    schedule 08.03.2017
comment
Так как же нам справиться с этим делом? - person Henry; 24.05.2018

Да, если взять один Ctrl + C, по крайней мере, под Linux будет. Вы можете проверить это с помощью следующего кода Python 3:

import time

try:
    print('In try.')
    time.sleep(1000)
finally:
    print('  <-- Note the Ctrl+C.')
    for i in range(1, 6):
        print(f'Finishing up part {i} of 5.')
        time.sleep(.1)

Вот результат:

$ ./finally.py
In try.
^C  <-- Note the Ctrl+C.
Finishing up part 1 of 5.
Finishing up part 2 of 5.
Finishing up part 3 of 5.
Finishing up part 4 of 5.
Finishing up part 5 of 5.
Traceback (most recent call last):
  File "./finally.py", line 7, in <module>
    time.sleep(1000)
KeyboardInterrupt
person Acumenus    schedule 22.12.2016

Да, обычно это вызывает исключение KeyboardInterrupt, но помните, что ваше приложение может быть неожиданно завершено в любое время, поэтому вам не следует полагаться на это.

person Neme    schedule 22.12.2016