How to run one last function before getting killed in Python?

前端 未结 5 1936
不思量自难忘°
不思量自难忘° 2020-12-08 20:17

Is there any way to run one last command before a running Python script is stopped by being killed by some other script, keyboard interrupt etc.

相关标签:
5条回答
  • 2020-12-08 20:33
    import time
    
    try:
        time.sleep(10)
    finally:
        print "clean up"
        
    clean up
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    KeyboardInterrupt
    

    If you need to catch other OS level interrupts, look at the signal module:

    http://docs.python.org/library/signal.html

    Signal Example

    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)
    
    0 讨论(0)
  • 2020-12-08 20:35
    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
    
    0 讨论(0)
  • 2020-12-08 20:45

    Use the atexit module to register a function that will be called at the end.

    import atexit
    atexit.register(some_function)
    
    0 讨论(0)
  • 2020-12-08 20:46

    WIth apologies to 'Unknown' for taking their answer and correcting it as though it was my own answer, but my edits were rejected.

    The approved answer contains an error that will cause a segfault.

    You cannot use sys.exit() in a signal handler, but you can use os._exit so that it becomes:

    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)
    

    SIGBREAK may be used if the target platform is Windows.

    Depending on the use case and the need to cleanup in the event of fatal errors - you may add SIGSEGV and SIGILL but generally this is not advised since the program state may be such that you create an infinite loop.

    0 讨论(0)
  • 2020-12-08 20:50

    You could use the atexit module. With it, you can register a function which will be called at program termination. An example from here: 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)
    

    You can also pass positional and keyword parameters to the function you want to call at program termination.

    Note that there are a few circumstances listed in the docs in which your handler won't be called:

    Note: The functions registered via this module are not called when the program is killed by a signal not handled by Python, when a Python fatal internal error is detected, or when os._exit() is called.

    As such, you may want to also register a signal handler.

    0 讨论(0)
提交回复
热议问题