2013-05-27 3 views
1

Я использую выход и задачи, чтобы получить четыре jsons асинхронно:Python: как вернуться из функции генератора с помощью торнадо?

@gen.engine 
def get_user_data(self, sn, snid, fast_withdrawals): 
    end_timestamp = time.time() 
    start_timestamp = end_timestamp - CONFIG.LOYALITY_LEVELS.PERIOD 

    active_apps_response, total_payments_response, payments_for_period_response, withdrawals_response = yield [ 
     gen.Task(self.http_client.fetch, self.__get_active_apps_url(sn, snid)), gen.Task(self.http_client.fetch, self.__get_total_payments_url(sn, snid)), 
     gen.Task(self.http_client.fetch, self.__get_payments_sum_for_period_url(sn, snid, start_timestamp, end_timestamp)), 
     gen.Task(self.http_client.fetch, self.__get_total_withdrawals_url(sn, snid, fast_withdrawals)) 
    ] 

    active_apps = self.__active_apps_handler(active_apps_response) 
    total_payments = self.__get_total_payments_handler(total_payments_response) 
    payments_for_period = self.__payments_sum_for_period_handler(payments_for_period_response) 
    withdrawals = self.__get_total_withdrawals_handler(withdrawals_response) 

    yield gen.Return(active_apps, total_payments, payments_for_period, withdrawals) 

Но если я с помощью выхода вместо возврата верхней функции стал генератор тоже, и я не могу использовать возврат в нем тоже. Итак, как вернуть результаты функции в торнадо без создания генератора функций звонящего? Я использую Python 2.7

ответ

4

Вы не можете возвращать значения и значения доходности. Когда вы возвращаете значения, функция возвращает генератор, поэтому она уже вернула значение и больше не может вернуться. Это просто не имеет смысла.

Вы можете позвонить return без каких-либо значений, чтобы вызвать исключение StopIteration и завершить генератор, но возврат значения не имеет смысла семантически изнутри генератора.

Если вы хотите вернуться к генератору и иногда возвращать значение, оберните свою функцию другим, который возвращает либо генератор (созданный при вызове этой функции), либо альтернативное значение, хотя я бы этого не делал как правило, плохая идея с дизайнерской точки зрения.

0

может быть, вы можете написать так:

@gen.coroutine 
def get_user_data(self, sn, snid, fast_withdrawals): 
    end_timestamp = time.time() 
    start_timestamp = end_timestamp - CONFIG.LOYALITY_LEVELS.PERIOD 

    active_apps_response, total_payments_response, payments_for_period_response, withdrawals_response = yield [ 
    self.http_client.fetch(self.__get_active_apps_url(sn, snid)), 
    self.http_client.fetch(self.__get_total_payments_url(sn, snid)), 
    self.http_client.fetch(self.__get_payments_sum_for_period_url(sn, snid, start_timestamp, end_timestamp)), 
    self.http_client.fetch(self.__get_total_withdrawals_url(sn, snid, fast_withdrawals)) 
] 

active_apps = self.__active_apps_handler(active_apps_response) 
total_payments = self.__get_total_payments_handler(total_payments_response) 
payments_for_period = self.__payments_sum_for_period_handler(payments_for_period_response) 
withdrawals = self.__get_total_withdrawals_handler(withdrawals_response) 

raise gen.Return(active_apps, total_payments, payments_for_period, withdrawals) 

двигателем является старым интерфейсом; подробнее об этом вы можете увидеть документ торнадо 3.0.

Смежные вопросы