使用inlineCallbacks

use*_*932 8 python twisted deferred

我是Twisted的新手,我正在尝试编写一个显示数据库名称列表的简单资源,这是我的代码的一部分:

#code from my ContactResource class
def render_GET(self, request):
    def print_contacts(contacts, request):
        for c in contacts:
            request.write(c.name)
        if not request.finished:
            request.finish()
    d = Contact.find() #Contact is a Twistar DBObject subclass
    d.addCallback(print_contacts, request)
    return NOT_DONE_YET
Run Code Online (Sandbox Code Playgroud)

我的问题是:如何更改此方法以使用inlineCallbacks装饰器?

Jea*_*one 11

一个render_GET方法可能无法返回Deferred.它可能只返回一个字符串或NOT_DONE_YET.装饰的任何方法inlineCallbacks都会返回一个Deferred.所以,你可能不装饰render_GETinlineCallbacks.

当然,没有什么可以阻止你调用你想要的任何其他函数render_GET,包括一个返回一个函数Deferred.只是扔掉Deferred而不是从它返回render_GET(当然,确保Deferred永远不会发生故障,或者扔掉它可能会丢失一些错误报告...).

所以,例如:

@inlineCallbacks
def _renderContacts(self, request):
    contacts = yield Contact.find() 
    for c in contacts:
        request.write(c.name)
    if not request.finished:
        request.finish()


def render_GET(self, request):
    self._renderContacts(request)
    return NOT_DONE_YET
Run Code Online (Sandbox Code Playgroud)

如果您要使用Twisted进行任何严肃的Web开发,我建议至少看看txyogaklein.即使您不想使用它们,它们也应该为您提供一些关于如何构建代码并完成各种常见任务的好主意.


sch*_*mar -2

编辑:我没有找到如何将twisted.web 与inlineCallbacks 结合起来的示例,但这里有两个建议。第一个是更好的选择,但我不确定它是否有效。

@inlineCallbacks
def render_GET(self, request):
    contacts = yield Contact.find() 
    defer.returnValue(''.join(c.name for c in contacts)


@inlineCallbacks
def render_GET(self, request):
    contacts = yield Contact.find() 
    for c in contacts:
        request.write(c.name)
    if not request.finished:
        request.finish()
    defer.returnValue(NOT_DONE_YET)
Run Code Online (Sandbox Code Playgroud)