Использование 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)