私のやり方:
実際の処理コードをクラスに入れ、そのクラスにPickleプロトコル(http://docs.python.org/library/pickle.html)を実装します(基本的に、適切な関数を記述__getstate__
し__setstate__
ます)
このクラスは、ファイル名を受け入れ、開いているファイルを保持し、CSVリーダーインスタンスをインスタンスメンバーとして保持します。この__getstate__
メソッドは現在のファイル位置を保存し、setstateはファイルを再度開き、適切な位置に転送して、新しいリーダーを作成します。
実際の作業は、__iter__
各行が処理された後に外部関数に出力されるメソッドで実行します。
この外部関数は、割り込み(ソケット、キーボード、ファイルシステム上の特定のファイルの状態など)の入力を監視する「メインループ」を実行します。すべてが静かで、プロセッサの次の反復を呼び出すだけです。割り込みが発生すると、プロセッサの状態がディスク上の特定のファイルにピクルスされます。
プログラムを起動するときは、実行が保存されているかどうかを確認する必要があります。保存されている場合は、pickleを使用してエグゼキュータオブジェクトを取得し、メインループを再開します。
ここにいくつかの(テストされていない)コードがあります-ieaは十分に単純です:
from cPickle import load, dump
import csv
import os, sys
SAVEFILE = "running.pkl"
STOPNOWFILE = "stop.now"
class Processor(object):
def __init__(self, filename):
self.file = open(filename, "rt")
self.reader = csv.reader(self.file)
def __iter__(self):
for line in self.reader():
# do stuff
yield None
def __getstate__(self):
return (self.file.name, self.file.tell())
def __setstate__(self, state):
self.file = open(state[0],"rt")
self.file.seek(state[1])
self.reader = csv.reader(self.File)
def check_for_interrupts():
# Use your imagination here!
# One simple thing would e to check for the existence of an specific file
# on disk.
# But you go all the way up to instantiate a tcp server and listen to
# interruptions on the network
if os.path.exists(STOPNOWFILE):
return True
return False
def main():
if os.path.exists(SAVEFILE):
with open(SAVEFILE) as savefile:
processor = load(savefile)
os.unlink(savefile)
else:
#Assumes the name of the .csv file to be passed on the command line
processor = Processor(sys.argv[1])
for line in processor:
if check_for_interrupts():
with open(SAVEFILE, "wb") as savefile:
dump(processor)
break
if __name__ == "__main__":
main()