3

I have a global instance, which I expect to be destroyed (function __del__ called) when the Python interpreter exits. Am I expecting too much of the Python interpreter? My method of testing this is to put a print in the __del__ function, run python.exe from a command line, and then pressing Ctrl/Break. At this point, I would expect to see the print in the command-line window. However, I do not.

lqc
  • 7,434
  • 1
  • 25
  • 25
barak manos
  • 29,648
  • 10
  • 62
  • 114
  • OK, I have noticed a difference between terminating the Python interpreter with Ctrl/Break (__del__ not called) and with Ctrl/C (__del__ called). I therefore assume that the Ctrl/Break kills the process, whereas Ctrl/C ends it properly. What should I expect from closing the window then? (perhaps this question should be asked in a different forum though). – barak manos Mar 20 '13 at 23:30
  • also of interest: http://stackoverflow.com/q/14628486/748858 – mgilson Mar 20 '13 at 23:41
  • 1
    And another reason you shouldn't rely on `__del__`: http://stackoverflow.com/a/14323849/748858 – mgilson Mar 20 '13 at 23:45

2 Answers2

7

Yes, you're expecting too much. Python doesn't make any guarantees about calling __del__:

It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits.

Edit:

Generally, you should avoid using __del__. For most cases context managers are better. For the rare case when you need to make sure that some external (i.e. allocated from C code) resource gets cleaned up when the interpreter exits you can use the atexit module.

lqc
  • 7,434
  • 1
  • 25
  • 25
  • My aim is to save the current state into a database just before the executable instance (which contains the global object in memory) is terminated. Is it conceptually wrong to perform DB operations in the destructor? – barak manos Mar 20 '13 at 23:37
4

You could add a handler for the signal.SIGBREAK signal. That would let you intercept ctrl + break. Form the documentation:

import signal, os

def handler(signum, frame):
    print 'Someone is trying to exit!', signum

signal.signal(signal.SIGBREAK, handler)
Jason Sperske
  • 29,816
  • 8
  • 73
  • 124