2

誰かが次の違いを説明してください。私は Deferred のコンセプトを理解するのに本当に苦労しています。しかし、私はコードブラインドでなければならないと思います。本当にシンプルだと思います。

これは機能します。

from twisted.spread import pb
from twisted.internet import reactor
from twisted.python import util


if __name__ == '__main__':

    def print_result(result):
        print result

    def add_numbers(obj, a, b):
        obj.callRemote("add_numbers", a, b)



    factory = pb.PBClientFactory()
    reactor.connectTCP("localhost", 8789, factory)
    d = factory.getRootObject()
    d.addCallback(lambda object: object.callRemote("add_numbers", 1, 2))
    d.addErrback(lambda reason: 'error: '+str(reason.value))
    d.addCallback(print_result)
    d.addErrback(lambda reason: 'error: '+str(reason.value))
    d.addCallback(lambda _: reactor.stop())
    d = factory.getRootObject()

    reactor.run()

そして、これはしません

from twisted.spread import pb
from twisted.internet import reactor
from twisted.python import util


if __name__ == '__main__':

    def print_result(result):
        print result

    def add_numbers(obj, a, b):
        obj.callRemote("add_numbers", a, b)



    factory = pb.PBClientFactory()
    reactor.connectTCP("localhost", 8789, factory)
    d = factory.getRootObject()
    d.addCallback(add_numbers, 1, 2)
    d.addErrback(lambda reason: 'error: '+str(reason.value))
    d.addCallback(print_result)
    d.addErrback(lambda reason: 'error: '+str(reason.value))
    d.addCallback(lambda _: reactor.stop())
    d = factory.getRootObject()

    reactor.run()

私は一生、理由を理解できません。次のエラーでクラッシュします。

Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
Failure: twisted.spread.pb.PBConnectionLost: [Failure instance: Traceback (failure  with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion: Connection lost.
]

サーバー側のコードは

from twisted.spread import pb
from twisted.internet import reactor

class Echoer(pb.Root):
    def remote_echo(self, st):
        print 'echoing:', st
        return st

    def remote_add_numbers(self, a, b):
        print 'adding:', a, b
        c = a + b
        return c

if __name__ == '__main__':
    reactor.listenTCP(8789, pb.PBServerFactory(Echoer()))
    reactor.run()
4

1 に答える 1

2

実際の例と壊れた例の違いは、lambda式が暗黙的に結果を返すことです。その結果は ですDeferred。これは、チェーン内の次のコールバックが、その結果が利用可能になるまで実行を待機することを意味します。

の定義をadd_numbersの結果を返すように変更するとcallRemote、次のようになります。

def add_numbers(obj, a, b):
    return obj.callRemote("add_numbers", a, b)

その後、壊れた例が再び機能し始めます。

于 2013-11-30T12:09:09.480 に答える