title: Python Object Lifetime Characteristics
body: <p>Note : if you know of any (non-elaborate) library code that does what I want please enlighten a C/C++ programmer, I'll accept that as answer.</p>
  
  <p>I have a global variable set to an instance of the following class. It's purpose is to allow me to set some manual interruption points to place some quick and dirty <code>printf</code> style debug points in a scrapy spider (I specifically need to break when certain criteria are met to tune a parser, there are some extremely rare input data anomalies) -- Adapted from <a href="http://docs.python.org/faq/library#id12" rel="nofollow">this</a>.</p>
  
  <p>Os is OS X 10.8.</p>
  
  <pre><code>import termios, fcntl, sys, os
  
  class DebugWaitKeypress(object):
      def __init__(self):
          self.fd = sys.stdin.fileno()
          self.oldterm = termios.tcgetattr(self.fd)
          self.newattr = termios.tcgetattr(self.fd)
          self.newattr[3] = self.newattr[3] &amp; ~termios.ICANON &amp; ~termios.ECHO
          termios.tcsetattr(self.fd, termios.TCSANOW, self.newattr)
  
          self.oldflags = fcntl.fcntl(self.fd, fcntl.F_GETFL)
          fcntl.fcntl(self.fd, fcntl.F_SETFL, self.oldflags | os.O_NONBLOCK)
  
      def wait(self):
          sys.stdin.read(1)
  
      def __del__(self):
          print "called del"
          termios.tcsetattr(self.fd, termios.TCSAFLUSH, self.oldterm)
          fcntl.fcntl(self.fd, fcntl.F_SETFL, self.oldflags)
  </code></pre>
  
  <p>When I press Ctrl-C and the process is unwinding I get the following exception :</p>
  
  <pre><code>Exception AttributeError: "'NoneType' object has no attribute 'tcsetattr'" in &lt;bound method DebugWaitKeypress.__del__ of &lt;hon.spiders.custom_debug.DebugWaitKeypress object at 0x108985e50&gt;&gt; ignored
  </code></pre>
  
  <p>I'm missing something about the mechanics of object lifetimes I guess ? How do remedy the situation. AFAIK any class instances should be destroyed before the imported code does, no ? in reverse order of declaration/definition.</p>
  
  <p>I would just ignore this if the terminal wasn't screwed up after the process exits :D</p>
  
  <p><strong>edit:</strong></p>
  
  <p>Delian's comment on seth's answer led me to understand that I need to use a C <code>main()</code> like function, or any other function/generator which dominates as a root function and initialise the context there. This way When the process is going down the <code>__exit__</code> method of the context manager will get called. And I won't have to reprogram the terminal stream on each <code>wait()</code> call. </p>
  
  <p>Although the cost of the reprogramming is potentially immaterial, it is good to know how one would these essential C/C++ semantics in python.</p>
  
  <p><strong>edit 2:</strong></p>
  
  <p>Twisted (which scrapy uses) goes apeshit when messing with stdin. So I had to solve the problem with file IO.</p>