注意:如果您知道我想要的任何(非精細)庫代碼,請啓發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