1

私は最近 Twisted を学んでいます。ちょうど今、Deferred の基本的なドキュメントを読み直しています

2番目にコメントアウトするのはどうg = Getter()ですか?再入力の問題はありますか?この種の問題を回避する方法について何か良いアイデアはありますか?

from twisted.internet import reactor, defer

class Getter:
    def gotResults(self, x):
        """
        The Deferred mechanism provides a mechanism to signal error
        conditions.  In this case, odd numbers are bad.

        This function demonstrates a more complex way of starting
        the callback chain by checking for expected results and
        choosing whether to fire the callback or errback chain
        """
        if self.d is None:
            print "Nowhere to put results"
            return

        d = self.d
        self.d = None
        if x % 2 == 0:
            d.callback(x*3)
        else:
            d.errback(ValueError("You used an odd number!"))

    def _toHTML(self, r):
        """
        This function converts r to HTML.

        It is added to the callback chain by getDummyData in
        order to demonstrate how a callback passes its own result
        to the next callback
        """
        return "Result: %s" % r

    def getDummyData(self, x):
        """
        The Deferred mechanism allows for chained callbacks.
        In this example, the output of gotResults is first
        passed through _toHTML on its way to printData.

        Again this function is a dummy, simulating a delayed result
        using callLater, rather than using a real asynchronous
        setup.
        """
        self.d = defer.Deferred()
        # simulate a delayed result by asking the reactor to schedule
        # gotResults in 2 seconds time
        reactor.callLater(2, self.gotResults, x)
        self.d.addCallback(self._toHTML)
        return self.d

def printData(d):
    print d

def printError(failure):
    import sys
    sys.stderr.write(str(failure))

# this series of callbacks and errbacks will print an error message
g = Getter()
d = g.getDummyData(3)
d.addCallback(printData)
d.addErrback(printError)

# this series of callbacks and errbacks will print "Result: 12"
#g = Getter() #<= What about commenting this line out? 
d = g.getDummyData(4)
d.addCallback(printData)
d.addErrback(printError)

reactor.callLater(4, reactor.stop)
reactor.run()
4

1 に答える 1

1

はい、2 番目の にコメントするg = Getter()と、問題が発生します。オブジェクトに保存されているため、同じDeferredことが2回発生します。特に、 の 2 番目の呼び出しは、最初の を上書きします。DeferredGettergetDummyDataDeferred

これを行うべきではありません。一般的なポイントとして、オブジェクトを保持するのは良い考えではないと思います。Deferredオブジェクトは 1 回しか発火できず、あなたのような問題が発生しやすいからです。

あなたがすべきことはこれです:

def getDummyData(self, x):
    ...
    d = defer.Deferred()
    # simulate a delayed result by asking the reactor to schedule
    # gotResults in 2 seconds time
    reactor.callLater(2, self.gotResults, x, d)
    d.addCallback(self._toHTML)
    return d

と:

def gotResults(self, x, d):
    """
    The Deferred mechanism provides a mechanism to signal error
    conditions.  In this case, odd numbers are bad.

    This function demonstrates a more complex way of starting
    the callback chain by checking for expected results and
    choosing whether to fire the callback or errback chain
    """
    if d is None:
        print "Nowhere to put results"
        return

    if x % 2 == 0:
        d.callback(x*3)
    else:
        d.errback(ValueError("You used an odd number!"))

この場合、状態がないことに注意してくださいGetter。これは良いことであり、そのためのクラスは必要ありません!

私の意見では、Deferreds を使用して、関数の呼び出し元に、結果が利用可能になったときに何かを実行できるようにする必要があります。凝ったものには使用しないでください。だから、私はいつも持っています

def func():
    d = defer.Deferred()
    ...
    return d

発信者がDeferredなんらかの理由で を保持しなければならない場合は、保持される可能性がありますが、func隠れ状態を気にせずに自由に何度でも呼び出すことができます。

于 2013-10-22T21:49:36.083 に答える