twisted学習-4 defer非同期コールバック

6208 ワード

defer03.py

from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic

class FingerProtocol(basic.LineReceiver):
    def lineReceived(self, user):
        d = self.factory.getUser(user)

        def onError(err):
            return 'Internal error in server'
        d.addErrback(onError)

        def writeResponse(message):
            self.transport.write(message + '\r
')             self.transport.loseConnection()         d.addCallback(writeResponse) class FingerFactory(protocol.ServerFactory):     protocol = FingerProtocol     def __init__(self, **kwargs):         self.users = kwargs     def getUser(self, user):         return defer.succeed(self.users.get(user, "No such user"))                #succeed: Return a Deferred that has already had .callback(result) called. reactor.listenTCP(1079, FingerFactory(moshez='Happy and well')) reactor.run()

この例は完全に前のfinger 07と同じである.pyは同じですが、deferが追加されただけです.ここで最も重要なのはdeferの属性がどのように伝達されているかです.
前の章から、コールバックを使用するにはdeferを定義する必要があることがわかりました.Deferred().これでcallbackとaddcallbackの方法を使用することができます.
しかし、上の実列ではdeferは見つかりませんでした.Deferred().これはなぜですか.
次の列はすべてを説明します
>>>from twisted.internet import defer
>>> dir(defer.succeed)
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
>>> dir(defer.succeed(3*3))
['__doc__', '__init__', '__module__', '__repr__', '__str__', '_canceller', '_chainedTo', '_continuation', '_debugInfo', '_runCallbacks', '_runningCallbacks', '_startRunCallbacks', '_suppressAlreadyCalled', 'addBoth', 'addCallback', 'addCallbacks', 'addErrback', 'callback', 'callbacks', 'called', 'cancel', 'chainDeferred', 'debug', 'errback', 'pause', 'paused', 'result', 'unpause']

   defer.succeedには本来コールバックの方法はありませんが、1つのオブジェクトに対して成功すると、コールバックの方法があります.これが上のコードがコールバックを使用できる理由の鍵です.

  defer04.py

from twisted.internet import protocol, reactor, defer, utils
from twisted.protocols import basic

class FingerProtocol(basic.LineReceiver):
    def lineReceived(self, user):
        d = self.factory.getUser(user)                       # d=utils.getProcessOutput("ls", [user])

        def onError(err):                                    # 
            return 'Internal error in server'
        d.addErrback(onError)                                # 。

        def writeResponse(message):                          # 
            self.transport.write(message + '\r
')             self.transport.loseConnection()         d.addCallback(writeResponse)                         # , class FingerFactory(protocol.ServerFactory):     protocol = FingerProtocol     def getUser(self, user):         return utils.getProcessOutput("ls", [user])                  #  , <Deferred at 0x1537290> , , reactor.listenTCP(1079, FingerFactory()) reactor.run()

このコードは実は上のコードと似ていて、同じ方法でコールバック属性を取得しています.以下に説明する.
>>> from twisted.internet import protocol, reactor, defer, utils
>>> dir(utils.getProcessOutput)
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
>>> dir(utils.getProcessOutput('ls','-alrt'))
['__doc__', '__init__', '__module__', '__repr__', '__str__', '_canceller', '_chainedTo', '_continuation', '_debugInfo', '_runCallbacks', '_runningCallbacks', '_startRunCallbacks', '_suppressAlreadyCalled', 'addBoth', 'addCallback', 'addCallbacks', 'addErrback', 'callback', 'callbacks', 'called', 'cancel', 'chainDeferred', 'debug', 'errback', 'pause', 'paused', 'unpause']

このコードをテストします
 
 :
[root@localhost ~]# telnet 127.0.0.1 1079                              # 
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
-l                                                                     # -l   
total 28                                                               # , 
-rw-r--r--. 1 root root  807 Aug 13 18:09 defer.py
-rw-r--r--. 1 root root 2137 May 19 22:16 echoserver.py
-rw-r--r--. 1 root root  422 May 20 01:59 stu_01.py
-rw-r--r--. 1 root root  496 May 20 02:00 stu_02.py
-rw-r--r--. 1 root root  604 May 20 02:22 stu_03.py
-rw-r--r--. 1 root root  834 May 20 02:49 stu_04.py
-rw-r--r--. 1 root root  368 Aug 12 16:57 test.py

Connection closed by foreign host.                                     # 
[root@localhost ~]#

皆さんは必ず流れを覚えてください.
関数はdeferredをバインドし、関数はdeferredを解放します.