Twisted features a decorator named inlineCallbacks which allows you to work with deferreds without writing callback functions.
This is done by writing your code as generators, which yield deferreds instead of attaching callbacks.
Consider the following function written in the traditional deferred style:
import txredisapi as redis from twisted.internet import defer from twisted.internet import reactor def main(): rc = redis.Connection() print rc rc.addCallback(onSuccess) rc.addErrback(onFail) def onSuccess(result): print "Success : " print result def onFail(result): print "Fail : " print result if __name__ == '__main__': main() reactor.run()
using inlineCallbacks, we can write this as:
from twisted.internet.defer import inlineCallbacks
import txredisapi as redis from twisted.internet import defer from twisted.internet import reactor @defer.inlineCallbacks def main(): rc = yield redis.Connection() print rc yield rc.set("abc", "pqr") v = yield rc.get("abc") print "value : ", repr(v) yield rc.disconnect() if __name__ == "__main__": main() reactor.run()
Instead of calling addCallback on the deferred returned by redis.Connection, we yield it. this causes Twisted to return the deferred‘s result to us.
Though the inlineCallbacks looks like synchronous code, which blocks while waiting for the request to finish, each yield statement allows other code to run while waiting for the deferred being yielded to fire.
inlineCallbacks become even more powerful when dealing with complex control flow and error handling.