-->

When is KeyboardInterrupt raised in Python?

2019-04-22 17:59发布

问题:

All the docs tell us is,

Raised when the user hits the interrupt key (normally Control-C or Delete). During execution, a check for interrupts is made regularly.

But from the point of the code, when can I see this exception? Does it occur during statement execution? Only between statements? Can it happen in the middle of an expression?

For example:

file_ = open('foo')
# <-- can a KeyboardInterrupt be raised here, after the successful
# completion of open but prior to the try? -->
try:
    # try some things with file_
finally:
    # cleanup

Will this code leak during a well-timed KeyboardInterrupt? Or is it raised during the execution of some statements or expressions?

回答1:

According to a note in the unrelated PEP 343:

Even if you write bug-free code, a KeyboardInterrupt exception can still cause it to exit between any two virtual machine opcodes.

So it can occur essentially anywhere. It can indeed occur during evaluation of a single expression. (This shouldn't be surprising, since an expression can include function calls, and pretty much anything can happen inside a function call.)



回答2:

Yes, a KeyboardInterrupt can occur in the place you marked.

To deal with this, you should use a with block:

with open('foo') as file_:
    # do some things
    raise KeyboardInterrupt

# file resource is closed no matter what, even if a KeyboardInterrupt is raised

However, the exception could occur even between the open() call and the assignment to file_. It's probably not worth worrying about this, because usually a ctrl-c will mean your program is about to end, so the "leaked" file handle will be cleaned up by the OS. But if you know that it is important, you can use a signal handler to catch the signal that raises KeyboardInterrupt (SIGINT).