title: del self vs self.__del__() - and what is the proper way to cleanup in python?
body: <p>I have a python script that contains a class. </p>
  
  <p>This class has a <code>__del__</code> method for usual cleanup. If I delete the class during the normal execution of the script, I want some cleanup to be done. </p>
  
  <p>I also have a signal handler, that does some unusual cleanup. If the script was in the middle of executing something else when it received the signal, it needs to do some extra cleanup, followed by the regular cleanup.</p>
  
  <p>I noticed there is a difference between doing <code>del self</code> and <code>self.__del__()</code>.</p>
  
  <p>Namely, <code>self.__del__()</code> calls the <code>del</code> method twice.</p>
  
  <p>Can you please explain why this happens?</p>
  
  <p>This is a mockup script to illustrate the issue:</p>
  
  <pre><code>import sys
  import signal
  from optparse import OptionParser
  
  
  class TestClass(object):
      def __init__(self,
                   del_self):
          self.del_self = del_self
  
          print "__init__ with del_self = %s" % self.del_self
  
      def __del__(self):
          print "Now performing usual cleanup."
  
      def signal_handler(self, arg_1, arg_2):
          print "Received signal. Now performing unusual cleanup."
  
          # Unusual cleanup
  
          print "Did unusual cleanup"
  
          if self.del_self:
              print("Doing del self")
              del self
          else:
              print("Doing self.__del__()")
              self.__del__()
  
          sys.exit(0)
  
  
  if __name__ == '__main__':
      arguments = sys.argv[1:]
      parse = OptionParser("Test.")
      parse.add_option(
          "-d",
          "--delself",
          help="Set del self.",
          type="int",
          default=1
      )
  
      (options, _) = parse.parse_args()
  
      print "Options: %s" % options
  
      tc = TestClass(del_self=options.delself)
  
      signal.signal(signal.SIGQUIT, tc.signal_handler)
  
      while True:
          pass
  </code></pre>
  
  <p>If I ran the script with:</p>
  
  <pre><code>python deltest.py --delself 1
  </code></pre>
  
  <p>And issue <code>killall -3 python</code> I get:</p>
  
  <pre><code>Received signal. Now performing unusual cleanup.
  Did unusual cleanup
  Doing del self
  Now performing usual cleanup.
  </code></pre>
  
  <p>Where as, if I do <code>python deltest.py --delself 0</code> again followed by the kill signal, i get:</p>
  
  <pre><code>Received signal. Now performing unusual cleanup.
  Did unusual cleanup
  Doing self.__del__()
  Now performing usual cleanup.
  Now performing usual cleanup.
  </code></pre>
  
  <p>Why is the <code>__del__</code> method executed twice in this case?</p>
  
  <p>Thanks!</p>