Python中是否有某种方法可以捕获KeyboardInterrupt
事件而不将所有代码放在try
- except
语句中?
如果用户按Ctrl+,我想干净利落地退出C.
是的,您可以使用模块信号安装中断处理程序,并使用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()
如果您想要的只是不显示回溯,请使用以下代码:
## 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)
设置自己的信号处理程序的另一种方法是使用上下文管理器来捕获异常并忽略它:
>>> 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
块,同时保留一些明确提及正在发生的事情.
这也允许您仅在代码的某些部分忽略中断,而无需每次都设置和重置信号处理程序.
我知道这是一个老问题,但我先来到这里,然后发现了atexit
模块.我不知道它的跨平台跟踪记录或完整的警告列表,但到目前为止,它正是我在寻求处理KeyboardInterrupt
Linux上的后清理时所寻求的.只是想提出另一种解决问题的方法.
我想在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模块帖子,一个很好的介绍