如何提示用户是否确定要在 KeyboardInterrupt 上退出程序?

瑞奇·威尔逊

当我按下 ctrl-c 时,屏幕上会弹出提示,我输入 no,因为我想继续运行该程序,但无论如何该程序都会退出。我哪里错了?这个功能甚至可能吗?

from functools import wraps
import sys

class CleanExit(object):
    def __init__(self, *args, **kw):
        # You can supply an optional function
        # to be called when the KeyboardInterrupt
        # takes place.
        # If the function doesn't require any arguments:
        #     @CleanExit(handler=func)
        # If the function requires arguments:
        #     @CleanExit('foo', handler=handle)

        self.kw = kw
        self.args = args
        self.handler = kw.get('handler')

    def __call__(self, original_func):
        decorator_self = self
        @wraps(original_func)
        def wrappee(*args, **kwargs):
            try:
                original_func(*args,**kwargs)
            except KeyboardInterrupt:
                if self.handler:
                    self.handler(*self.args)
                else:
                    sys.exit(0)
        return wrappee

def handle():
    answer = raw_input("Are you sure you want to exit?").lower().strip()
    if 'y' in answer:
        sys.exit(0)

@CleanExit(handler=handle)
def f():
    while 1: pass

f()
艾萨克·范东根

您的问题是您在处理函数后没有做任何事情来继续该函数 - 因此您的代码处理中断,然后无论如何退出。如果处理程序像这样成功退出,您可以递归地重新输入 wrappee:

    def __call__(self, original_func):
        decorator_self = self
        @wraps(original_func)
        def wrappee(*args, **kwargs):
            try:
                original_func(*args,**kwargs)
            except KeyboardInterrupt:
                if self.handler:
                    self.handler(*self.args)
                    wrappee(*args, **kwargs)
                else:
                    sys.exit(0)
        return wrappee

现在这应该有效。请注意,这有点顽皮,因为 Python 无法优化尾调用,因此如果您KeyboardInterrupt经常使用sys.getrecursionlimit(),Python 将耗尽堆栈帧并崩溃。

编辑:那太愚蠢了——仔细想想,这个函数对于手动递归来说是如此微不足道,它甚至可能都不算数。

    def __call__(self, original_func):
        decorator_self = self
        @wraps(original_func)
        def wrappee(*args, **kwargs):
            while True:
                try:
                    original_func(*args,**kwargs)
                except KeyboardInterrupt:
                    if self.handler:
                        self.handler(*self.args)
                    else:
                        sys.exit(0)
        return wrappee

也应该工作得很好。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使Pool对KeyboardInterrupt敏感

Selenium 不会在 KeyboardInterrupt (Python) 上退出

如何在不使用KeyboardInterrupt的情况下从按键退出while循环?[蟒蛇]

如何使用 Ctrl+C 等效中断 Python 后台守护程序(强制 KeyboardInterrupt 异常)

在Windows上的python中未捕获KeyboardInterrupt

无法关闭KeyboardInterrupt上的套接字

KeyboardInterrupt在不同的执行方式上的行为不同

有没有办法永远不会在Python的KeyboardInterrupt上退出?

在芹菜工作者退出之前在KeyboardInterrupt上执行一些操作

为什么异步事件循环会抑制Windows上的KeyboardInterrupt?

如何从Windows 10上卡住的全屏应用程序退出?

如何在backpress上退出android应用程序?

如何在Mac上退出Electron应用程序?

如何检测Android上的应用程序退出?

如何确定要在Nvidia Jetson TK1上重新安装哪个驱动程序?

如何从主进程使用KeyboardInterrupt停止子进程?

pyzmq龙卷风ioloop:如何正常处理KeyboardInterrupt?

如何防止代码块被Python中的KeyboardInterrupt中断?

如何在python-trio中的KeyboardInterrupt之后清理连接

如何确保我的 KeyboardInterrupt except 会做我需要的事情

如何检测Windows上python中退出的程序并在退出时执行某些操作

像KVM这样的管理程序是否需要在CPUID上退出VM?

如何确定要在哪个驱动器上保存文本文件?

如何退出程序?

如何成功退出程序

Python:Tornado ioloop在KeyboardInterrupt上毫无例外地被杀死

无法在命令提示符下两次捕获KeyboardInterrupt?

如果选择退出选项,如何退出程序?

Ionic 2-如何在Android上使用后退按钮退出应用程序?