注意:如果您知道我想要的任何(非精细)库代码,请启发C/C++程序员,我将接受该答案作为答案。Python对象生命周期特征
我有一个全局变量设置为以下类的一个实例。它的目的是允许我设置一些手动中断点,以便在scrapy蜘蛛中放置一些快速且脏的样式调试点(当特定标准符合调谐解析器时,我特别需要中断,还有一些非常罕见的输入数据异常) - 改编自this。
Os是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
编辑:
提洛对Seth的回答评论使我明白,我需要使用类似于函数,或者作为根函数支配并在那里初始化上下文的任何其他函数/生成器。这种方式当进程正在关闭时,上下文管理器的__exit__
方法将被调用。我不需要在每个wait()
调用上重新编程终端流。
尽管重新编程的代价可能并不重要,但知道Python中这些基本的C/C++语义如何是很好的。
编辑2:用标准输入搞乱当
扭曲(其scrapy用途)变为apeshit。所以我必须用文件IO来解决问题。
嗯有没有其他的上下文管理器可能的结构?该文档似乎表明该构造可用于语句块。这意味着每次我想要打断点时,我必须重新配置终端两次。 – 2012-08-10 01:30:30
@HassanSyed你似乎低估了它。作为*任何*(甚至friggin的导入和类定义,尽管你很难找到一个好的用例)可以进入上下文管理器,例如,你可以将调用包装到你的'main'函数中一个,它会在发生任何事情之前配置终端,并且仅当'main'离开时重置配置(通常由于异常导致*或*)。就像你可以在C++的'main'中的堆栈上创建'DebugWaitKeypress'一样。 – delnan 2012-08-10 01:33:10
嗯,这是我认为我需要的洞察力。我可以在作为生成器实现的scrapy的'parse'方法中初始化一个全局类,我在生成器的顶部启动上下文,然后当我用完url时返回生成器超出范围,它在scrapy之前开始关闭。 – 2012-08-10 01:42:48