Я пишу модуль, который печатает свой прогресс по мере загрузки данных, выполняет некоторые вычисления и сохраняет результат, примерно так:
def process_data():
print('Loading data...')
data = load_data()
print('Data loaded. Starting calculations...')
result = calculate(data)
print('Calculations complete. Saving result...')
save_result(result)
print('Done.')
Я хочу подключить этот модуль с представлением Djangoчтобы конечный пользователь мог видеть ход выполнения операторов print
во время его выполнения. Это представляется возможным при использовании StreamingHttpResponse
, который принимает итератор и отправляет любой текст yield
в браузер во время его работы. До сих пор я добился определенного успеха, изменив print
на yield
в основной функции. Но когда я попытался изменить print
на yield
в функции calculate
, получилось довольно грязно:
from django.http import StreamingHttpResponse
def process_data_view(request):
return StreamingHttpResponse(process_data())
def process_data():
yield '<pre>Loading data...\n'
data = load_data()
yield 'Data loaded. Starting calculations...\n'
# Here's where it got messy:
for printline_or_result in calculate(data):
# when calculate function yields a string, take it as a line to print
if isinstance(printline_or_result, str):
yield printline_or_result
# when calculate function yields a non-string, take it as the result
else:
result = printline_or_result
yield 'Calculations complete. Saving result...\n'
save_result(result)
yield 'Done.\n'
Есть ли лучший способ захватить строки, которые будут напечатаны, и выдать ихDjango?
Редактировать: Этот связанный вопрос о захвате операторов печати интересен, но я все еще не могу понять, как получить результат.
Edit2: Похоже yield from может обрабатывать генераторы, которые также возвращают значение, так что это может решить мой сценарий использования, хотя я должен написать все функции как генераторы и все вызовы функций, используя yield from
... «Беспорядочная» часть выше простостать result = yield from calculate(data)
.