Вам не хватает только одной строки!
import signal
interruptLoop = False
def interrupt_handler(sig, frame):
global interruptLoop # You're missing this
interruptLoop = True
signal.signal(signal.SIGINT, interrupt_handler) # handle ctrl+c
count = 0
while not interruptLoop:
print(count); count += 1
print("I'm done!")
Если вы запустите это, вы увидите напечатанные цифры, пока не нажмете Ctrl+C
, и в этот момент вы увидите: «Ясделанный!"и скрипт завершится.
Почему был необходим global interruptLoop
?
Python не требует, чтобы вы объявляли переменные в своей области действия функции.Чтобы определить, какие переменные определены локально для функции, нужно посмотреть, какие переменные установлены.Поэтому, когда вы устанавливаете interruptLoop = True
в interrupt_handler
, python видит это как сигнал, что interrupt_handler
имеет локальную переменную.Эта локальная переменная затеняет внешнюю область видимости interruptLoop
, которую питон рассматривает как отдельную.Таким образом, ваш обработчик, по сути, просто создает локальную переменную, модифицирует ее и затем завершает работу.Конечно, это не останавливает цикл (который зависит от внешней области видимости interruptLoop
).Ключевое слово global
сигнализирует python, что внутренняя переменная должна ссылаться на внешнюю, а не скрывать ее.Для получения дополнительной информации см. здесь для краткого объяснения и здесь для полного обсуждения переменной области видимости Python.