В настоящее время я пишу набор инструментов , которые я использую для своих исследований.Одним из таких инструментов является способ автоматически отправлять уведомления, когда длительный процесс завершается или останавливается.Эти сообщения могут быть электронными письмами и могут захватывать выходные данные, которые генерирует кусок кода, например (или больше примеров ):
>>> stream = io.StringIO()
>>> notify = NotifyViaStream("testtask", stream)
>>> # set a custom template used to stringify the notifications
>>> notify.notification_template = "{task} {reason} {output}"
>>> with notify.when_done():
... # potentially long-running process
... print('testoutput')
>>> stream.getvalue()
'testtask done testoutput'
Проблема, которую я пытаюсьЧтобы решить сейчас, это особенно долго выполняемые задачи, такие как печать индикаторов выполнения, чтобы информировать пользователя о текущем состоянии.Таким образом, они часто используют возврат каретки \r
, чтобы переместить курсор в начало строки и перезаписать всю строку, чтобы обновить индикатор выполнения.Однако при отправке (текстовых) электронных писем этот caputured вывод (содержащий \r
s, конечно, не будет отображаться так. Вместо этого каждое обновление печатается в новой строке, что приводит к беспорядочным выводам, например:
running RTEDataset fs=(3, 4, 5), nb_f=128
Epoch 1/3
1/77 [..............................] - ETA: 8:12 - loss: 1.0988 - acc: 0.3750
2/77 [..............................] - ETA: 4:21 - loss: 0.9525 - acc: 0.5156
3/77 [>.............................] - ETA: 3:03 - loss: 0.8636 - acc: 0.5625
4/77 [>.............................] - ETA: 2:24 - loss: 0.9153 - acc: 0.5312
5/77 [>.............................] - ETA: 2:01 - loss: 0.9294 - acc: 0.5250
6/77 [=>............................] - ETA: 1:45 - loss: 0.9078 - acc: 0.5417
7/77 [=>............................] - ETA: 1:33 - loss: 0.9101 - acc: 0.5268
... and so on
Каков наилучший способ «предварительного рендеринга» вывода, который будет получен на эмуляторе терминала? Есть ли что-нибудь умнее, если просто использовать регулярное выражение для сопоставления всего от начала строки до \r и заменяя ее пустой строкой? Это уже не будет работать, если следующая строка не полностью перезапишет последнюю, например:
test\routput\rback
будет напечатано как backut
на терминале, но как back
используя этот простой подход.
Есть ли питонный способ добиться этого без использования внешних библиотек (возможно, с использованием ncursed
или даже на стороне клиента в почтовом клиенте?)
Бонусный вопрос : сделаете ли вы поведение настраиваемым, чтобы явно не обрабатывать (или даже удалять) возврат каретки?значение по умолчанию?