无法在Python中中止(Ctrl + C)

时间:2018-11-15 18:41:16

标签: python python-3.x exception exception-handling keyboardinterrupt

如果输入的不是整数,我编写此代码是为了不断要求更多的输入。但是,当我尝试在python交互式会话中中止它时,它一直要求输入。

即使我按Ctrl + C,这也为什么会这样做?

def get_size(text):
    while True:
        try:
            i = int(input(text))
            if i >= 0 and i<24:
                break
        except:
            pass
    return i

a = get_size("Input: ")

3 个答案:

答案 0 :(得分:2)

当您按下 Ctrl + C 时,Python解释器捕获中断并引发KeyboardInterrupt异常。因为裸露的except等效于except BaseException,并且KeyboardInterruptBaseException的子类,所以except将捕获KeyboardInterruptexcept块中没有异常处理(例如重新引发),因此程序将继续。

至少将except更改为except Exception,因为属于BaseException子类但不属于ExceptionKeyboardInterrupt子类的异常, SystemExitGeneratorExit)并不是真的要被吞下。在极少数情况下,在重新饲养它们之前将它们捕获并进行一些清理是很有意义的。但是,几乎没有用例可以捕获它们,而不必再次提出它们。

可能方便的Python documentation actually contains a hierarchy visualization of built-in exceptions

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
      |    +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      ...

您可能会注意到except Exception 可以还会捕获一些您可能无法恢复的异常。例如MemoryErrorSyntaxErrorSystemError通常表示某事出了错(真的),并且不应吞下这些东西,因为这些 可能是“不可恢复的” ”(至少在大多数情况下)。

这意味着您应该观察代码可能会引发哪些异常以及在何种情况下引发异常,然后确定可以从哪些异常中恢复。

在您的情况下:

  • input()并非应该失败,因此您最好将其放在try之外。
  • 类似地,您不会期望比较失败,因此也可以将其放在try块之外。因为您只希望代码在try成功之后才能运行,所以您需要对其进行保护,例如在else的{​​{1}}块中。
  • 如果try是不受支持的类型,则可能由于int()而失败,但是TypeError总是返回字符串。字符串是input可接受的类型,因此不会想到会发生这种情况。
  • 因此,您可能在这里遇到的唯一“预期”异常是int()。如果无法将字符串解释为整数,则会引发该错误。

所以我会用:

ValueError

或者,如果您不想使用def get_size(text): while True: input_text = input(text) try: i = int(input_text) except ValueError: pass else: if 0 <= i < 24: return i 块,也可以在else块中使用continue

except

您使用的哪一个主要取决于偏好。两者应该工作相同。

总结一下:

  • 从您的角度确定允许失败的最小代码量,不要在def get_size(text): while True: input_text = input(text) try: i = int(input_text) except ValueError: continue if 0 <= i < 24: return i 块中放入其他任何内容。
  • 确保仅捕获“可恢复”异常。在大多数情况下,异常类型就足够了。但是有时检查异常消息以确保它确实是您要捕获的异常可能很有意义。
  • 请勿使用tryexcept:。唯一的例外是,如果您确实想抓住except BaseException:SystemExitKeyboardInterrupt并知道如何适当处理它们。您可能会放弃使用GeneratorExit,但是对于要定期使用的任何代码(或在生产代码中使用的代码),您应该花时间寻找更合适的异常。

答案 1 :(得分:1)

Ctrl + C的意思是KeyboardInterrupt,但是您的except块会捕获并忽略它(以及所有其他异常)。甚至Ctrl + D也不会停止执行,所以我认为您应该终止该过程。

答案 2 :(得分:0)

您在try:循环内创建了except: while块。因此,每当脚本抛出错误时,except就会通过并返回到while循环。