有没有办法在运行的 Python 脚本被其他脚本、键盘中断等杀死之前运行最后一个命令?
问问题
29908 次
5 回答
43
import time
try:
time.sleep(10)
finally:
print "clean up"
clean up
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt
如果需要捕捉其他操作系统级别的中断,看信号模块:
http://docs.python.org/library/signal.html
信号示例
from signal import *
import sys, time
def clean(*args):
print "clean me"
sys.exit(0)
for sig in (SIGABRT, SIGBREAK, SIGILL, SIGINT, SIGSEGV, SIGTERM):
signal(sig, clean)
time.sleep(10)
于 2009-05-30T20:29:50.813 回答
13
您可以使用该atexit
模块。使用它,您可以注册一个将在程序终止时调用的函数。这里的一个例子:http: //docs.python.org/library/atexit.html
try:
_count = int(open("/tmp/counter").read())
except IOError:
_count = 0
def incrcounter(n):
global _count
_count = _count + n
def savecounter():
open("/tmp/counter", "w").write("%d" % _count)
import atexit
atexit.register(savecounter)
您还可以将位置和关键字参数传递给要在程序终止时调用的函数。
请注意,文档中列出了一些不会调用您的处理程序的情况:
注意:当程序被未由 Python 处理的信号杀死、检测到 Python 致命内部错误或被调用时,不会调用通过此模块注册的函数
os._exit()
。
因此,您可能还想注册一个信号处理程序。
于 2009-05-30T20:32:14.617 回答
10
import signal
import sys
import time
def cleanup(*args):
print 'Exiting'
sys.exit(0)
signal.signal(signal.SIGINT, cleanup)
signal.signal(signal.SIGTERM, cleanup)
while True:
time.sleep(60) # less busy loop
于 2009-05-30T20:24:34.257 回答
8
向“未知”道歉,因为他们接受了他们的答案并进行了更正,就好像这是我自己的答案一样,但我的编辑被拒绝了。
批准的答案包含将导致段错误的错误。
您不能在信号处理程序中使用 sys.exit(),但可以使用 os._exit 使其变为:
from signal import *
import os, time
def clean(*args):
print "clean me"
os._exit(0)
for sig in (SIGABRT, SIGINT, SIGTERM):
signal(sig, clean)
time.sleep(10)
如果目标平台是 Windows,则可以使用 SIGBREAK。
根据用例和在发生致命错误时清理的需要 - 您可以添加 SIGSEGV 和 SIGILL 但通常不建议这样做,因为程序状态可能会导致您创建无限循环。
于 2016-01-03T09:55:32.433 回答
6
使用 atexit 模块注册一个将在最后调用的函数。
import atexit
atexit.register(some_function)
于 2009-05-30T20:32:20.683 回答