python随时终止你的程序?

时间:2014-08-26 18:02:36

标签: python

我希望能够在任何时间运行后结束我的程序。类似于我按ctrl + c并且它表示键盘中断,但我不想要像

这样的东西
if "keyboard press here" == true:
  quit()

我之所以不希望它如上所述是因为我的代码似乎会一直运行直到它到达我的代码的这一部分。有命令

编辑:

很抱歉,如果我不清楚我的问题。我的意思是,我不希望我的程序必须达到它所说的位置"按键盘退出"在我的程序中,但在每个空间都有它。例如,如果我有一个看起来像这样的while循环:

while True
print "1"
print "2"
if "keyboard press here" == true:
      quit()
print "3"
print "4"

我必须等到它打印出来

>>>1
>>>2

之前我可以按键盘停止或者如果它通过2并打印3它就像这样

>>>1
>>>2
>>>3
>>>4
>>>1
>>>2

然后我的程序就会停止。

我想让我的程序像这样工作:

while True
    print "1"
    if "keyboard press here" == true:
          quit()
    print "2"
    if "keyboard press here" == true:
          quit()
    print "3"
    if "keyboard press here" == true:
          quit()
    print "4"
    if "keyboard press here" == true:
          quit()

但我不想继续推送

if "keyboard press here" == true: quit()
每隔一个空间。有没有办法做到这一点?

5 个答案:

答案 0 :(得分:3)

嗯,它不漂亮,但我能想到的只是处理键盘中断......

while True:
    try:
        # your main code here   
    except KeyboardInterrupt:
        break # or quit(), or sys.exit()

编辑:

要回答您更新的问题:

  

我的意思是我不希望我的程序必须达到目的   它在我的程序中说“按键盘退出”的地方,但要拥有它   在每个空间

嗯,你没必要,尝试 - 除了你想要的。 要将此代码应用于更新的答案:

while True:
    try:
        print "1"
        print "2"
        print "3"
        print "4"
    except KeyboardInterrupt:
        break

答案 1 :(得分:2)

您可以创建一个信号处理程序,或使用您自己的excepthook覆盖。

信号处理程序

信号处理程序可能有帮助。

import sys
import signal


def terminate(signal, frame):
    print("received SIGINT, exit..." file=sys.stderr)
    sys.exit(0)

signal.signal(signal.SIGINT, terminate)

for i in range(0, 100000):
    print(i)

但要注意信号处理程序,你应该非常小心地编写信号处理程序。即使对于有经验的UNIX C程序员来说,编写正确的信号处理程序也很困难。

当一个程序收到一个信号时,它会被暂停。

例如,print()在流工作时阻塞流或IO设备,当生成信号时,它将暂停以执行信号处理程序。这一次,因此当前print()尚未返回时,您无法调用(可重入)print(),因为它仍然持有流/设备。

更糟糕的是,当前信号处理程序仍在运行时,将触发信号。因此,信号处理程序和所有函数必须允许重入调用。

但它在Python中更容易,更安全,因为Python做了所有必要的工作,允许核心功能重新进入。

异常挂钩

引用错误来自哪里?当有未处理的异常时,Python将调用一个特殊函数(sys.__excepthook__)来打印引用。

你可以覆盖它并做任何额外的事情(除了引发一个未处理的异常以避免无限递归^ _ ^),你不需要考虑可重入的问题。

我们经常使用此功能将错误记录到日志文件或弹出警告窗口。但它适合你的情况。

import sys


def my_excepthook(type, value, traceback):
    if type is KeyboardInterrupt:
        print("got KeyboardInterrupt, exit...")
        sys.exit(0)
    else:
        # call the original hook to print the trackback properly
        sys.__excepthook__(type, value, traceback)

sys.excepthook = my_excepthook

for i in range(0, 100000):
    print(i)
BTW,一个警告,这两种方法适用于多线程编程,但是你需要做的不仅仅是示例,而是要更加小心。

答案 2 :(得分:0)

要做你想做的事情你的代码必须在一个无限循环中运行,这是否实际取决于你正在编写的程序类型。

假设这段代码处于一个无限循环中,并且你没有任何可以减慢它的睡眠时间,那就做几乎就是你所做的。

你是正确的,因为程序必须在语句生效之前达到执行点,但由于你处于一个运行速度非常快的无限循环中,对用户来说,时间似乎是即时的。

编辑:取决于循环的大小以及您的程序是否会在任何大量时间内处于休眠状态,您可能会发现需要将条件放在多个位置你的循环。

(很可能一次在顶部,然后在每次睡眠后一次)

进一步编辑以回应评论1& 2关于这个答案:
我要做的是:

 flag=False
 while True:
      if flag:
         quit() # or break or whatever you want to do

      print 1
      print 2
      #press to continue function to prompt and get key press/ set variable goes here....
      if pressed:
         flag=True
         continue
      print 3 
      print 4
      .....

告诉程序“继续”将使它开始下一个循环itteration立即bur,因为你已经设置了标志,程序将无法运行。

但是,我不确定我是否完全理解你想要的东西,因为根据这个逻辑,你可以简单地说:

if pressed:
   sys.exit()

我意识到你现在想要的东西,你只是想要处理中断,例如塞巴斯蒂安说,或者像其他人一样使用信号处理程序

答案 3 :(得分:0)

尽我所知,您希望能够以类似于ctrl-c但使用不同键盘序列的方式终止程序。一种方法是将你的stdin阅读器放入一个不同的线程,让它杀死自己的程序。主线程可以捕获KeyboardInterrupt,这样你就不会在最后获得python堆栈跟踪。

import os
import sys
import threading
import time
import signal

def kill_handler():
    data = sys.stdin.read(1)
    os.kill(os.getpid(), signal.SIGINT)

def main():
    kill_thread = threading.Thread(target=kill_handler)
    kill_thread.daemon = True
    kill_thread.start()

    print "press enter to terminate"
    try:
        while True:
            print 1
            time.sleep(.5)
            print 2
            time.sleep(.5)
            print 3
            time.sleep(.5)
            print 4
            time.sleep(.5)
    except KeyboardInterrupt:
        print "terminating"

if __name__=='__main__':
    main()

答案 4 :(得分:0)

我认为您想要的行为是让您的程序在每一步之后停止并询问您是否要继续?

执行此操作的一种非常脏的方法是从pdb(python调试器)中运行程序。在程序顶部或循环的第一行设置断点:

import pdb
pdb.set_trace()

然后,当您执行该程序时,您将被带到pdb提示符。在每一步,您都可以输入下一步'或者' n'继续。如果要退出调试器并让程序自然完成,请输入' c' (对于'继续')。如果要退出,请输入ctrl + D.

如果此程序仅供您个人使用,那么这将是您获得所需内容的简便方法。但是,如果你打算分发它,那么它显然是不可能的。