私はゆっくりと、しかし確実にひねりのコツをつかんでいますが、この特定のプロジェクトにどのようにアプローチすればよいかわかりません.
Web ページのバッチ処理用のクラスを作成しようとしています。個別に処理したい Web ページが複数あるため、各 URL に対してある種のパイプラインを用意することは理にかなっています。さらに、いずれかの URL が処理される前に 1 回限りの前処理関数を呼び出したいと思います。すべての URL が処理されたら、後処理関数を呼び出したいと思います。重要なのは、この処理クラスをサブクラス化し、処理しようとしているコンテンツに基づいて特定のメソッドをオーバーライドできるようにしたいということです。すべての Web ページで同じ処理手順が必要になるわけではありません。
これが同期コードである場合、おそらくコンテキスト マネージャーを使用してこれを行います。次のコード例を検討してください。
class Pipeline(object):
def __init__(self, urls):
self.urls = urls # iterable
self.continue = False
def __enter__(self):
self.continue = self.preprocess()
def __exit__(self, type, value, traceback):
if self.continue: # if we decided to run the batch pipeline...
self.postprocess()
def preprocess(self):
# does some stuff and returns a bool
def postprocess(self):
# do some stuff
def pipeline(self):
for url in self.urls:
try:
# download url, do some stuff
except:
# recover so that other urls are not interrupted
その後、次のように使用します。
with Pipeline(list_of_urls) as p:
p.pipeline()
これは、同期ネットワーク操作ではうまく機能しますが、Twisted では機能しません。パイプライン関数は、処理パイプラインの終了前に戻り、 を呼び出すため__exit__
です。
さらに、クエリの結果に基づいて条件分岐が発生する可能性があるため、各 URL の処理を完全に個別に実行したいと考えています。このため、Twisted を使用するDeferredList
ことは望ましくありません。
一言で言えば、次のものが必要です。
- 前処理は何よりも先に実行する必要があります
- 次の条件に当てはまる場合、後処理を実行する必要があります。
- 少なくとも 1 つの URL が処理を開始しました (前処理が を返します
True
) - すべての URL が完了したか、例外をスローしました
- 少なくとも 1 つの URL が処理を開始しました (前処理が を返します
Twisted でこのようなものを設定する最も健全な方法は何ですか? 私が抱えている問題は、一部のコードには非同期 IO が含まれており、一部は単純な同期ロジック (つまり、結果をメモリ内で処理する) であるため、すべてを deferred で機能させる方法がわかりません (または、すべきです)。
何かアドバイス?