Características de tempo de vida do objeto Python

Nota: se você souber de algum código de biblioteca (não elaborado) que faz o que eu quero, por favor, ilumine um programador C / C ++, eu aceito isso como resposta.

Eu tenho uma variável global definida para uma instância da seguinte classe. Sua finalidade é permitir que eu defina alguns pontos de interrupção manual para colocar alguns pontos rápidos e sujosprintf estilo pontos de depuração em uma aranha escamosa (eu especificamente preciso quebrar quando certos critérios são atendidos para sintonizar um analisador, existem algumas anomalias de dados de entrada extremamente raras) - Adaptado deisto.

O é o 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)

Quando pressiono Ctrl-C e o processo é desenrolado, recebo a seguinte exceção:

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

Eu estou perdendo algo sobre a mecânica das vidas dos objetos, eu acho? Como remediar a situação. AFAIK qualquer instância de classe deve ser destruída antes do código importado, não? em ordem inversa da declaração / definição.

Eu apenas ignoraria isso se o terminal não for danificado depois que o processo terminar: D

editar:

O comentário de Delian sobre a resposta de seth me levou a entender que eu preciso usar um Cmain() como função, ou qualquer outra função / gerador que domina como uma função raiz e inicializa o contexto lá. Desta forma, quando o processo está indo para o__exit__ método do gerenciador de contexto será chamado. E eu não terei que reprogramar o fluxo do terminal em cadawait() ligar.

Embora o custo da reprogramação seja potencialmente imaterial, é bom saber como se poderia usar essa semântica essencial de C / C ++ em python.

edição 2:

Twisted (que usa scrapy) fica apeshit quando mexer com stdin. Então eu tive que resolver o problema com o arquivo IO.

questionAnswers(2)

yourAnswerToTheQuestion