gkhaos
gkhaos

Reputation: 705

Python Interactive Loop-Break

I'm currently trying to accomplish a loop which stops on user interaction.

My first idea was to use signals which brought me to this:

import signal

interruptLoop = False
def interrupt_handler(sig, frame):
        interruptLoop = True
signal.signal(signal.SIGINT, interrupt_handler) # handle ctrl+c

count = 0
while not interruptLoop:
    print count; count += 1

this results in an infinite loop, because the rise of interruptLoop does not affect the variable out of the handler scope.

I'd appreciate any advice about why python/signal behaves like that and how to accomplish my task. Thanks in advance.

Upvotes: 2

Views: 1825

Answers (1)

augray
augray

Reputation: 3161

You're only missing one line!

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!")

If you run this, you'll see the numbers printed until you hit Ctrl+C, at which point you'll see "I'm done!" and the script will exit.

Why was the global interruptLoop needed?

Python doesn't require you to declare variables in your function scope. The way it determines what variables are defined locally for a function is to see which variables are set. So when you set interruptLoop = True in interrupt_handler, python sees this as a cue that interrupt_handler has a local variable. This local variable shadows the outer-scope's interruptLoop, which python is treating as separate. So your handler essentially just creates a local variable, modifies it, and then exits. Of course this doesn't stop the loop (which depends on the outer scope's interruptLoop). The global keyword signals to python that the inner variable is actually supposed to reference the outer one rather than shadowing it. For more see here for a short explanation and here for a full discussion of python's variable scoping.

Upvotes: 2

Related Questions