如何关闭python脚本而不激活;除「;在try/except语句中

如何关闭python脚本而不激活;除「;在try/except语句中,python,Python,我有一个python脚本,在数据库中运行大约50000个项目,每个项目大约需要10秒,我想停止它 但是,如果在代码处于try-except部分时按ctrl+C,那么我的程序将输入expect语句并删除该项,然后继续。关闭程序的唯一方法是以这种方式反复删除项目,直到我(非常幸运)在try语句中发现它 如何在不终止try语句的情况下退出脚本 编辑1 我有一个类似这样的声明: for item in items: try: if is_item_gone(content) == 1:

我有一个python脚本,在数据库中运行大约50000个项目,每个项目大约需要10秒,我想停止它

但是,如果在代码处于try-except部分时按ctrl+C,那么我的程序将输入expect语句并删除该项,然后继续。关闭程序的唯一方法是以这种方式反复删除项目,直到我(非常幸运)在try语句中发现它

如何在不终止try语句的情况下退出脚本

编辑1

我有一个类似这样的声明:

for item in items:
   try:
      if is_item_gone(content) == 1:
         data = (item['id'])
         db.update('UPDATE items SET empty = 0 WHERE id = (%s);', data)
      else:
          do alot of stuff
   except:
      data = (item['id'])
      db.delete('...')
try:
    # ...
except KeyboardInterrupt:
    sys.exit(1)
except Exception:  # I would use a more specific exception here if you can.
    data = (item['id'])
    db.delete('...')
编辑2

“连接到数据库”代码的顶部如下所示:

#!/usr/bin/python
import MySQLdb
import sys

class Database:
....
这将在任何给定的时间注册并捕获实例Ctrl+c。处理程序将相应地终止套接字,然后使用退出代码0退出,这是一个好的退出代码


这是一种更为“全局”的捕获键盘中断的方法。

问题在于,您使用的是一个毯子,除非这始终是一个坏主意,如果捕获特定的异常,那么当您
键盘中断时,您的脚本将停止:

for item in items:
   try:
      if is_item_gone(content) == 1:
         data = (item['id'])
         db.update('UPDATE items SET empty = 0 WHERE id = (%s);', data)
      else:
          do alot of stuff
   except MySQLdb.Error  as e:
      print(e)
      data = (item['id'])
      db.delete('...')
如果要捕获其他异常,可以在中使用多个,但以下情况除外:

 except (KeyError, MySQLdb.Error) as e
至少您可以将
异常捕获为e
并打印错误

for item in items:
   try:
      if is_item_gone(content) == 1:
         data = (item['id'])
         db.update('UPDATE items SET empty = 0 WHERE id = (%s);', data)
      else:
          do alot of stuff
   except Exception as e:  
      print(e)
      data = (item['id'])
      db.delete('...')

这个故事的寓意是不要使用毯子,除非,抓住你所期望的,并记录错误也可能是一个好主意。这本书也值得一读,看看你到底抓住了什么

我会这样重写它:

for item in items:
   try:
      if is_item_gone(content) == 1:
         data = (item['id'])
         db.update('UPDATE items SET empty = 0 WHERE id = (%s);', data)
      else:
          do alot of stuff
   except:
      data = (item['id'])
      db.delete('...')
try:
    # ...
except KeyboardInterrupt:
    sys.exit(1)
except Exception:  # I would use a more specific exception here if you can.
    data = (item['id'])
    db.delete('...')
或者只是

try:
    # ...
except Exception:  # I would use an even more specific exception here if you can.
    data = (item['id'])
    db.delete('...')
Python 2的异常层次结构可以在以下位置找到:

此外,许多脚本在底部使用类似于锅炉板的东西编写:

def _main(args):
   ...

if __name__ == '__main__':
    try:
        sys.exit(_main(sys.argv[1:]))
    except KeyboardInterrupt:
        print >> sys.stderr, '%s: interrupted' % _SCRIPT_NAME
        sys.exit(1)

当您在主体中使用
except:
而不是
Exception:
时,您不允许此顶级异常块捕获
键盘中断。(你不必捕捉它,Ctrl-C就可以工作——这只会使它在出现
键盘中断时更漂亮。)

除异常
而不是
除异常
。你捕捉到了什么异常?这个问题几乎可以肯定,因为你使用的是毯子,但这几乎总是一个坏主意,如果捕获特定异常,则ctrl+C将停止program@PadraicCunningham我现在添加了我的代码。是的,你的问题是,你用什么连接数据库?基本上你应该有
除了一些特定的异常
或者
除了一些特定的异常,另一个特定的异常
,因为你捕捉到了每一个异常,你捕捉到了键盘中断,所以脚本一直在运行如果你花时间否决投票内容,做一个好运动并解释原因。我们中的一些人实际上正在努力改进,没有适当的反馈很难做到这一点。(注意到否决票已经消失了,但是如果你正在读这篇文章或者计划否决,一定要写一张便条。)我没有否决你,但我认为你的解决方案并没有被认为是很好的。首先,OP不应该捕获所有异常,而应该更具体。其次,Ctrl-C的捕获有一个例外,这将使Ctrl-C处理代码保持在捕获它的块的本地:@rrauenza我想从技术上讲,这不是“Pythonic”,但它是线程友好的*nix标准捕获事件的方式,例如Ctrl+C(实际上,这是终止的信号,而不是其他)<代码>尝试
在我看来,应该保留用于孤立事件或实际代码问题,而不是用户/外部输入。但话说回来,现在人们似乎喜欢
try
catch,就像Visual Basic时代人们喜欢
goto
一样。我不知道,我想我老了,脾气暴躁了。无论如何,问题已经回答并标记为已解决,我想这里的工作已经完成了。@Rorschach是的,这段代码应该在脚本的顶部,以捕捉任何类型的“终止信号”。安全地停止线程、终止套接字而不必将大量代码块(如循环等)包装在丑陋的
try
catch中是非常有用的。尝试捕捉是好的,但要针对不同的情况使用适当的方法。在这种情况下,您希望捕获实际的SIGHUP信号(Ctrl+C),这是一个OS定义的用户输入,用于终止脚本。当然有一个
try
catch,但从本质上讲,它是一个信号,所以要这样对待它。注意,你实际上不需要捕捉
键盘中断
,Ctrl-C就可以工作了。。。您不必意外地用毛毯捕捉到它,除非:
。仅供参考:isinstance(键盘中断,异常)->False。KeyboardInterrupt不是从Exception派生的。@rrauenza,True,它直接从BaseException继承,GeneratorExit和SystemExit也是如此