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を解放します.