Использование inlineCallbacks

Я новичок в 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

Мой вопрос: как я могу изменить этот метод, чтобы использовать декоратор inlineCallbacks?

2 ответа

render_GET метод не может вернуть Deferred, Может возвращать только строку или NOT_DONE_YET, Любой метод украшен inlineCallbacks вернет Deferred, Таким образом, вы не можете украсить render_GET с inlineCallbacks,

Конечно, ничто не мешает вам вызывать любую другую функцию, которую вы хотите в 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

Я рекомендую хотя бы взглянуть на txyoga и klein, если вы собираетесь заниматься какой-либо серьезной веб-разработкой с Twisted. Даже если вы не хотите их использовать, они должны дать вам несколько хороших идей о том, как вы можете структурировать свой код и выполнять различные общие задачи, подобные этой.

Изменить: я не нашел пример, как объединить 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)
Другие вопросы по тегам