【发布时间】:2012-08-10 00:50:48
【问题描述】:
注意:如果您知道任何(非详尽的)库代码可以满足我的要求,请启发 C/C++ 程序员,我会接受它作为答案。
我有一个全局变量设置为以下类的一个实例。其目的是允许我设置一些手动中断点,以便在 scrapy 蜘蛛中放置一些快速而肮脏的printf 样式调试点(我特别需要在满足某些条件来调整解析器时中断,有一些极其罕见的输入数据异常)——改编自this。
操作系统是 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 回答的评论让我明白我需要使用 C main() 类似函数,或任何其他作为根函数占主导地位的函数/生成器并在那里初始化上下文。这样,当进程停止时,上下文管理器的__exit__ 方法将被调用。而且我不必在每次wait() 调用时重新编程终端流。
尽管重新编程的成本可能无关紧要,但最好知道如何在 python 中使用这些基本的 C/C++ 语义。
编辑 2:
在与标准输入混淆时,Twisted(scrapy 使用)会变得很糟糕。所以我不得不解决文件IO的问题。
【问题讨论】: