ホームページ  >  記事  >  バックエンド開発  >  Python の Twisted フレームワークにおける Deferred オブジェクトの使用法の分析例

Python の Twisted フレームワークにおける Deferred オブジェクトの使用法の分析例

高洛峰
高洛峰オリジナル
2017-02-03 16:22:531620ブラウズ

Deferred オブジェクトの構造
Deferred は一連のペアのコールバック チェーンで構成され、各ペアには成功を処理するためのコールバック (コールバック) とエラーを処理するためのコールバック (エラーバック) が含まれます。最初は、defered は 2 つの空のコールバック チェーンで構成されます。コールバックを追加するときは、常にペアで追加されます。非同期処理の結果が返されると、Deferred が開始され、追加された順序でコールバック チェーンがトリガーされます。
例を使って説明する方が簡単かもしれません。まず、addCallback を見てみましょう:

from twisted.internet.defer import Deferred
  
def myCallback(result):
  print result
  
d = Deferred()
d.addCallback(myCallback)
d.callback("Triggering callback.")

これを実行すると、次の結果が得られます:

Triggering callback.

上記の例では、defered が作成され、その addCallback メソッドが作成されます。成功ハンドラーを登録するために使用されます。 d.callback は遅延を開始し、コールバック チェーンを呼び出します。コールバックに渡されるパラメータは、各コールバック チェーンの最初の関数でも受信されます。
addCallback と、もう 1 つの間違ったブランチがありますが、それが addErrorback であることも推測できると思います。例を見てみましょう:

from twisted.internet.defer import Deferred
  
def myErrback(failure):
  print failure
  
d = Deferred()
d.addErrback(myErrback)
d.errback(ValueError("Triggering errback."))

それを実行すると、次の結果が得られます:

[Failure instance: Traceback (failure with no frames): <type &#39;exceptions.ValueError&#39;>: Triggering errback.]

Twisted であることがわかります。 Encapsulated in Failure エラーが削除されます。
前述したように、登録されたコールバックは常にペアであることに注意してください。 d.addCallback メソッドと d.addErrorback メソッドを使用する場合、コールバックまたはエラーバックを追加するだけのようです。実際、このレベルのコールバック チェーンの作成を完了するために、これらのメソッドは残りの半分のパススルーも登録します。コールバック チェーンは常に同じ長さであることに注意してください。このレベルのコールバックのコールバックとエラーバックをそれぞれ指定する場合。 d.addCallbacks メソッドを使用できます:

d = Deferred()
d.addCallbacks(myCallback, myErrback)
d.callback("Triggering callback.")

それでは...今日はここまでです。

高度な例
次のステップは、より実践的なことを行うことです。それは、Reactor を組み込むことです。まず例を見てみましょう:

from twisted.internet import reactor, defer
  
class HeadlineRetriever(object):
  def processHeadline(self, headline):
    if len(headline) > 50:
      self.d.errback(Exception("The headline ``%s&#39;&#39; is too long!" % (headline,)))
    else:
      self.d.callback(headline)
  
  def _toHTML(self, result):
    return "<h1>%s</h1>" % (result,)
  
  def getHeadline(self, input):
    self.d = defer.Deferred()
    reactor.callLater(1, self.processHeadline, input)
    self.d.addCallback(self._toHTML)
    return self.d
  
def printData(result):
  print result
  reactor.stop()
  
def printError(failure):
  print failure
  reactor.stop()
  
h = HeadlineRetriever()
d = h.getHeadline("Breaking News: Twisted Takes us to the Moon!")
d.addCallbacks(printData, printError)
  
reactor.run()

上記の例はタイトルを受け取り、それを処理します。タイトルが長すぎる場合は長すぎるエラーが返され、そうでない場合は HTML に変換されて返されます。

指定されたタイトルは 50 文字未満であるため、上記のコードを実行すると次の戻り値が返されます:

<h1>Breaking News: Twisted Takes us to the Moon!</h1>

注目に値する点の 1 つは、上記でリアクターの callLater メソッドが使用されていることです。これは、時間指定されたイベントの作成に使用できます。非同期リクエストをシミュレートします。

たとえば、タイトルを非常に長くすると、次のようになります:

h = HeadlineRetriever()
d = h.getHeadline("1234567890"*6)
d.addCallbacks(printData, printError)

結果は次のようになります:

[Failure instance: Traceback (failure with no frames): <type &#39;exceptions.Exception&#39;>: The headline ``123456789012345678901234567890123456789012345678901234567890&#39;&#39; is too long!]

トリガーのプロセスを図で見てみましょう:

Deferreds の重要なポイント
1.コールバックまたはエラーバックが呼び出されたときにトリガーされます。
2. 遅延は 1 回だけトリガーされます。複数回トリガーしようとすると、AlreadyCalledError 例外が発生します。
3. N レベルのコールバックまたはエラーバックの例外は、N+1 レベルのエラーバックに渡されます。 。 N 番目のレベルのコールバックまたはエラーバックが Exception をスローしないか、Failure オブジェクトを返さない場合、コールバックで返された結果は次のレベルのコールバックに渡されます。最初のパラメータ;
5. errback に渡されたエラーが Failure オブジェクトではない場合、自動的に一度ラップされます。

Python の Twisted フレームワークでの Deferred オブジェクトの使用法を分析するその他の例については、PHP 中国語 Web サイトの関連記事に注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。