Есть ли способ сохранить вывод консоли TQDM в файл?

#python #console #tqdm

Вопрос:

Я пытался сохранить индикатор выполнения tqdm из библиотеки Python tqdm в текстовый файл. Я попытался перенаправить файлы sys.stdout и sys.stderr в файл:

введите описание изображения здесь

Однако сохраняются только выходные данные из stdout (например, инструкции печати), а не индикаторы выполнения tqdm. Индикаторы выполнения остаются в консоли.

Комментарии:

1. всегда указывайте код, данные и полное сообщение об ошибке в виде текста (не скриншот, не ссылка) в вопросе (не в комментарии).

2. вам не нужно открывать один и тот же файл два раза — вы можете добавить один и тот же файл file handler в stdout и stderr . В некоторых системах вы даже можете получить ошибку, если попытаетесь записать в один и тот же файл два разных file handlers файла .

3. Мне интересно, почему вы хотите перенаправить его в файл. tqdm использует специальный символ r , чтобы перейти к началу строки и перепечатать новый текст, но в файле вы увидите r и весь текст — старый и новый — для каждого изменения в строке выполнения — что-то вроде [# ]r[## ]r[### ]r[####] . Если вам нужна какая-то информация tqdm , возможно, вам следует проверить callback , какие из них будут периодически выполняться с текущими значениями, а затем вы можете сохранить их в файле без перенаправления.

4. если я запущу tqdm с перенаправлением sys.stderr , то получу его в файле. Может быть, проблема в другом. Возможно tqdm , попадает sys в другой момент (в другом модуле), и он получает исходное значение sys.stderr . Лучше создайте минимальный рабочий код для вашей проблемы, а затем мы можем скопировать и запустить его, чтобы увидеть проблему и протестировать некоторые идеи.

5. Спасибо за совет, я новичок в том, чтобы задавать вопросы о переполнении стека. Я выполняю некоторые симуляции и хочу записать статистику времени (итерации/секунда), которую предоставляет tqdm, в дополнение к другим выводам моей программы. Вы получаете индикаторы выполнения tqdm в своем файле, когда перенаправляете его с помощью sys.stderr?

Ответ №1:

Если я перенаправлю sys.stderr на файл, то попаду tqdm в файл.

 import tqdm import time import sys  fh = open('output.txt', 'w') # one file for both `stdout` and `stderr`  original_stderr = sys.stderr sys.stderr = fh #original_stdout = sys.stdout #sys.stdout = fh  items = 100  for i in tqdm.tqdm(range(items)):  time.sleep(0.1)  sys.stderr = original_stderr #sys.stdout = original_stdout  fh.close()  

или я могу использовать tqdm(..., file=fh)

 import tqdm import time  fh = open('output.txt', 'w')  items = 100  for i in tqdm.tqdm(range(items), file=fh):  time.sleep(0.1)  fh.close()  

Но в этом файле есть что-то вроде этого

 0%| | 0/100 [00:00lt;?, ?it/s]  1%| | 1/100 [00:00lt;00:09, 9.98it/s]  2%|▏ | 2/100 [00:00lt;00:09, 9.84it/s]  3%|▎ | 3/100 [00:00lt;00:09, 9.87it/s]  4%|▍ | 4/100 [00:00lt;00:09, 9.90it/s]  5%|▌ | 5/100 [00:00lt;00:09, 9.92it/s]  6%|▌ | 6/100 [00:00lt;00:09, 9.93it/s]  7%|▋ | 7/100 [00:00lt;00:09, 9.93it/s]  8%|▊ | 8/100 [00:00lt;00:09, 9.94it/s]  9%|▉ | 9/100 [00:00lt;00:09, 9.94it/s]  10%|█ | 10/100 [00:01lt;00:09, 9.94it/s]  11%|█ | 11/100 [00:01lt;00:08, 9.94it/s]  12%|█▏ | 12/100 [00:01lt;00:08, 9.94it/s]  13%|█▎ | 13/100 [00:01lt;00:08, 9.95it/s]  14%|█▍ | 14/100 [00:01lt;00:08, 9.95it/s]  15%|█▌ | 15/100 [00:01lt;00:08, 9.95it/s]  16%|█▌ | 16/100 [00:01lt;00:08, 9.94it/s]  17%|█▋ | 17/100 [00:01lt;00:08, 9.95it/s]  18%|█▊ | 18/100 [00:01lt;00:08, 9.95it/s]  19%|█▉ | 19/100 [00:01lt;00:08, 9.95it/s]  20%|██ | 20/100 [00:02lt;00:08, 9.95it/s]  21%|██ | 21/100 [00:02lt;00:07, 9.95it/s]  

tqdm использует символ r для перехода к началу строки и печати нового текста.
Мой редактор в Linux отображает его в виде новых строк, но в Windows вы можете увидеть все это в одной строке, например

 0%| | 0/100 [00:00lt;?, ?it/s]r 1%| | 1/100 [00:00lt;00:09, 9.98it/s]r 2%|▏ | 2/100 [00:00lt;00:09, 9.84it/s]  

Если вы хотите получить окончательное значение it/s , то вы бы предпочли использовать time.time() и рассчитать его вручную.

 import tqdm import time import sys  items = 100  start = time.time()  for i in tqdm.tqdm(range(items)):  time.sleep(0.1)  end = time.time()  diff = end-start items_per_second = items/diff  print(f'time: {diff:.2f} s | {items_per_second:.2f} it/s')  

Результат:

 time: 10.09 s | 9.91 it/s  

И это вы можете записать в файл fh.write() , используя print(..., file=fh) или перенаправляя sys.stdout или перенаправляя при запуске кода в консоли/терминале

 python script.py gt; output.txt