注:私が望むことを行う(精巧ではない)ライブラリコードを知っている場合は、C / C ++プログラマーを啓発してください。それを答えとして受け入れます。
次のクラスのインスタンスに設定されたグローバル変数があります。その目的は、いくつかの手動中断ポイントを設定printf
して、スクレイピースパイダーにいくつかの迅速で汚いスタイルのデバッグポイントを配置できるようにすることです (特に、パーサーを調整するために特定の基準が満たされたときに中断する必要があります。非常にまれな入力データの異常があります)。 -これから適応。
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
私が推測するオブジェクトの寿命の仕組みについて何かが欠けていますか? 状況をどのように改善しますか。私の知る限り、インポートされたコードが破棄される前にクラスインスタンスを破棄する必要がありますか? 宣言/定義の逆順。
プロセスが終了した後に端末が台無しにならなかった場合、私はこれを無視します:D
編集:
セスの答えに対するデリアンのコメントにより、Cmain()
のような関数、またはルート関数として支配し、そこでコンテキストを初期化する他の関数/ジェネレーターを使用する必要があることがわかりました。このように、プロセスがダウンする__exit__
と、コンテキストマネージャーのメソッドが呼び出されます。wait()
また、呼び出しごとに端末ストリームを再プログラムする必要はありません。
再プログラミングのコストは潜在的に重要ではありませんが、Python でこれらの重要な C/C++ セマンティクスをどのように使用するかを知っておくとよいでしょう。
編集2:
Twisted (scrapy が使用する) は、stdin をいじると大騒ぎします。そのため、ファイル IO の問題を解決する必要がありました。