注意:如果您知道任何(非详细)库代码可以满足我的要求,请启发 C/C++ 程序员,我会接受它作为答案。
我有一个全局变量设置为以下类的实例。其目的是允许我设置一些手动中断点,以便printf
在 scrapy 蜘蛛中放置一些快速而肮脏的调试点(我特别需要在满足某些条件来调整解析器时中断,有一些极其罕见的输入数据异常) ——改编自此。
操作系统是 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)
当我按 Ctrl-C 并且进程正在展开时,我得到以下异常:
Exception AttributeError: "'NoneType' object has no attribute 'tcsetattr'" in <bound method DebugWaitKeypress.__del__ of <hon.spiders.custom_debug.DebugWaitKeypress object at 0x108985e50>> ignored
我想我错过了一些关于对象生命周期机制的东西?怎么补救这种情况。AFAIK 任何类实例都应该在导入代码之前被销毁,不是吗?以声明/定义的相反顺序。
如果在进程退出后终端没有搞砸,我会忽略这一点:D
编辑:
Delian 对 seth 的回答的评论让我明白我需要使用类似 Cmain()
的函数,或任何其他作为根函数占主导地位的函数/生成器并在那里初始化上下文。这样,当进程停止__exit__
时,上下文管理器的方法将被调用。而且我不必在每次wait()
通话时重新编程终端流。
尽管重新编程的成本可能无关紧要,但很高兴知道如何在 python 中使用这些基本的 C/C++ 语义。
编辑2:
与标准输入混淆时,Twisted(scrapy 使用)会变得很糟糕。所以我不得不解决文件IO的问题。