How to handle console exit and object destruction

蹲街弑〆低调 提交于 2021-02-11 09:47:52

问题


Given this code:

from time import sleep

class TemporaryFileCreator(object):
  def __init__(self):
    print 'create temporary file'
    # create_temp_file('temp.txt')

  def watch(self):
    try:
      print 'watching tempoary file'
      while True:
        # add_a_line_in_temp_file('temp.txt', 'new line')
        sleep(4)
    except (KeyboardInterrupt, SystemExit), e:
      print 'deleting the temporary file..'
      # delete_temporary_file('temp.txt')
      sleep(3)
      print str(e)



t = TemporaryFileCreator()
t.watch()

during the t.watch(), I want to close this application in the console..

I tried using CTRL+C and it works:

However, if I click the exit button:

it doesn't work.. I checked many related questions about this but it seems that I cannot find the right answer..

What I want to do:

The console can be exited while the program is still running.. to handle that, when the exit button is pressed, I want to make a cleanup of the objects (deleting of created temporary files), rollback of temporary changes, etc..

Question:

  1. how can I handle console exit?
  2. how can I integrate it on object destructors (__exit__())
  3. Is it even possible? (how about py2exe?)

Note: code will be compiled on py2exe.. "hopes that the effect is the same"


回答1:


You may want to have a look at signals. When a *nix terminal is closed with a running process, this process receives a couple signals. For instance this code waits for the SIGHUB hangup signal and writes a final message. This codes works under OSX and Linux. I know you are specifically asking for Windows but you might want to give it a shot or investigate what signals a Windows command prompt is emitting during shutdown.

import signal
import sys
def signal_handler(signal, frame):
            with open('./log.log', 'w') as f:
                f.write('event received!')

signal.signal(signal.SIGHUP, signal_handler)
print('Waiting for the final blow...')
#signal.pause() # does not work under windows
sleep(10) # so let us just wait here

Quote from the documentation:

On Windows, signal() can only be called with SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, or SIGTERM. A ValueError will be raised in any other case.

Update:

Actually, the closest thing in Windows is win32api.setConsoleCtrlHandler (doc). This was already discussed here:

When using win32api.setConsoleCtrlHandler(), I'm able to receive shutdown/logoff/etc events from Windows, and cleanly shut down my app.

And if Daniel's code still works, this might be a nice way to use both (signals and CtrlHandler) for cross-platform purposes:

import os, sys
def set_exit_handler(func):
    if os.name == "nt":
        try:
            import win32api
            win32api.SetConsoleCtrlHandler(func, True)
        except ImportError:
            version = “.”.join(map(str, sys.version_info[:2]))
            raise Exception(”pywin32 not installed for Python ” + version)
    else:
        import signal
        signal.signal(signal.SIGTERM, func)

if __name__ == "__main__":
    def on_exit(sig, func=None):
        print "exit handler triggered"
        import time
        time.sleep(5)

set_exit_handler(on_exit)
print "Press  to quit"
raw_input()
print "quit!"



回答2:


If you use tempfile to create your temporary file, it will be automatically deleted when the Python process is killed.

Try it with:

>>> foo = tempfile.NamedTemporaryFile()
>>> foo.name
'c:\\users\\blah\\appdata\\local\\temp\\tmpxxxxxx'

Now check that the named file is there. You can write to and read from this file like any other.
Now kill the Python window and check that file is gone (it should be)

You can simply call foo.close() to delete it manually in your code.



来源:https://stackoverflow.com/questions/36126165/how-to-handle-console-exit-and-object-destruction

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!