Características de vida útil del objeto Python

Nota: si conoce algún código de biblioteca (no elaborado) que haga lo que quiero, por favor ilumine a un programador de C / C ++, lo aceptaré como respuesta.

Tengo una variable global configurada para una instancia de la siguiente clase. Su propósito es permitirme establecer algunos puntos de interrupción manual para colocar algo rápido y sucioprintf puntos de depuración de estilo en una araña scrapy (específicamente necesito romper cuando se cumplen ciertos criterios para ajustar un analizador, hay algunas anomalías de datos de entrada extremadamente raras) - Adaptado deesta.

Os es OS X 10.8.

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] & ~termios.ICANON & ~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)

Cuando presiono Ctrl-C y el proceso se está desenrollando, obtengo la siguiente excepción:

Exception AttributeError: "'NoneType' object has no attribute 'tcsetattr'" in <bound method DebugWaitKeypress.__del__ of <hon.spiders.custom_debug.DebugWaitKeypress object at 0x108985e50>> ignored

Me estoy perdiendo algo sobre la mecánica de la vida de los objetos, supongo. ¿Cómo remediar la situación. AFAIK cualquier instancia de clase debe destruirse antes de que lo haga el código importado, ¿no? en orden inverso de declaración / definición.

Simplemente ignoraría esto si el terminal no se estropeara después de que el proceso finalice: D

editar:

El comentario de Delian sobre la respuesta de Seth me hizo comprender que necesito usar una Cmain() como la función, o cualquier otra función / generador que domine como una función raíz e inicialice el contexto allí. De esta manera, cuando el proceso va por el__exit__ Método del gestor de contexto será llamado. Y no tendré que reprogramar el flujo de terminal en cadawait() llamada.

Si bien el costo de la reprogramación es potencialmente irrelevante, es bueno saber cómo se haría esta semántica esencial de C / C ++ en python.

edición 2:

Twisted (que utiliza scrapy) se vuelve loco al jugar con stdin. Así que tuve que resolver el problema con el archivo IO.

Respuestas a la pregunta(2)

Su respuesta a la pregunta