当前位置:  开发笔记 > 编程语言 > 正文

在没有try-except的情况下捕获Python中的keyboardinterrupt

如何解决《在没有try-except的情况下捕获Python中的keyboardinterrupt》经验,为你挑选了4个好方法。

Python中是否有某种方法可以捕获KeyboardInterrupt事件而不将所有代码放在try- except语句中?

如果用户按Ctrl+,我想干净利落地退出C.



1> Johan Kotlin..:

是的,您可以使用模块信号安装中断处理程序,并使用threading.Event永远等待:

import signal
import sys
import time
import threading

def signal_handler(signal, frame):
    print('You pressed Ctrl+C!')
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)
print('Press Ctrl+C')
forever = threading.Event()
forever.wait()


请注意,信号模块存在一些特定于平台的问题 - 不应影响此海报,但"在Windows上,只能使用SIGABRT,SIGFPE,SIGILL,SIGINT,SIGSEGV或SIGTERM调用signal()."ValueError将在任何其他情况下被提出."
也适用于线程.我希望你永远不要做'虽然真的:继续'.(按照那种方式,"虽然真的:通过`会更整洁."这是非常浪费的; 尝试类似`while True:time.sleep(60*60*24)`(一次睡一天是完全随意的数字).
您可以使用signal.pause()而不是重复睡眠

2> bgporter..:

如果您想要的只是不显示回溯,请使用以下代码:

## all your app logic here
def main():
   ## whatever your app does.


if __name__ == "__main__":
   try:
      main()
   except KeyboardInterrupt:
      # do nothing here
      pass

(是的,我知道这并没有直接回答这个问题,但是不清楚为什么需要一个try/except块是令人反感的 - 也许这会让它不那么讨厌OP)


出于某种原因,这对我来说并不总是有效.`signal.signal(signal.SIGINT,lambda s,f:sys.exit(0))`总是这样.

3> Bakuriu..:

设置自己的信号处理程序的另一种方法是使用上下文管理器来捕获异常并忽略它:

>>> class CleanExit(object):
...     def __enter__(self):
...             return self
...     def __exit__(self, exc_type, exc_value, exc_tb):
...             if exc_type is KeyboardInterrupt:
...                     return True
...             return exc_type is None
... 
>>> with CleanExit():
...     input()    #just to test it
... 
>>>

这将删除try- except块,同时保留一些明确提及正在发生的事情.

这也允许您仅在代码的某些部分忽略中断,而无需每次都设置和重置信号处理程序.



4> driftcatcher..:

我知道这是一个老问题,但我先来到这里,然后发现了atexit模块.我不知道它的跨平台跟踪记录或完整的警告列表,但到目前为止,它正是我在寻求处理KeyboardInterruptLinux上的后清理时所寻求的.只是想提出另一种解决问题的方法.

我想在Fabric操作的上下文中进行退出后清理,因此将所有内容包装在try/ except中也不是我的选择.atexit在这种情况下,我觉得可能非常适合,因为您的代码不在控制流的顶层.

atexit 开箱即用,非常有能力和可读性,例如:

import atexit

def goodbye():
    print "You are now leaving the Python sector."

atexit.register(goodbye)

您也可以将它用作装饰器(从2.6开始;此示例来自文档):

import atexit

@atexit.register
def goodbye():
    print "You are now leaving the Python sector."

如果你只想让它具体化KeyboardInterrupt,那么另一个人对这个问题的回答可能更好.

但请注意,该atexit模块只有大约70行代码,并且创建一个以不同方式处理异常的类似版本并不难,例如将异常作为参数传递给回调函数.(这种限制atexit将保证修改版本:目前我无法设想退出回调函数的方式来了解异常; atexit处理程序捕获异常,调用您的回调,然后重新引发那个例外.但你可以这样做.)

有关详情,请参阅:

官方文件 atexit

本周的Python模块帖子,一个很好的介绍

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有