Reineke
@Reineke
Главный бутатор всего

Как правильно перезаписать вывод в консоль в python?

Использую Python 3.6.1.
Необходима, казалось бы, тривиальная вещь: при обработке файлов, нужно выводить запись типа "Обработано x файлов из y", где соответственно значение x должно обновляться.
Написал это примерно таким образом:
x = 0
y = len(ololo)
for lol in ololo:
    #обрабатываю lol как мне нужно
    x += 1
    print("\r Обработано %d из %d" % (x, y), end="", flush=True)

Вот только почему-то если следующей строкой не добавить sleep() (эксперементально причем заметил, значение должно быть не менее 0.3 секунды, чтобы всё работало корректно), то перевод строки срабатывает через раз и иногда следующая строка не обновляет предыдующую, а "прилипает" к ней следом. На форумах в примерах тоже везде видел, что добавляют sleep. Но решение это мне совсем не нравится, т.к. необходимо обработать огромное количество данных, и при каждой итерации тратить впустую 0.3 секунды - достаточно затратно.
Прошу помощи, что я делаю не так и как это можно исправить? Спасибо.
  • Вопрос задан
  • 3032 просмотра
Решения вопроса 1
bonv
@bonv
Мой рабочий вариант прогрессора

import sys

def progress(count, total, suffix=''):
    bar_len = 40
    filled_len = int(round(bar_len * count / float(total)))

    percents = round(100.0 * count / float(total), 1)
    bar = '=' * filled_len + '-' * (bar_len - filled_len)

    sys.stdout.write('[%s] %s%s ...%s\r' % (bar, percents, '%', suffix))
    sys.stdout.flush()

    
def test():
    for i in range(1000000):
        progress(i, 1000000, 'обработано')
        
        
test()
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
x = 0
y = len('ololo')
for lol in 'ololo':
    # обрабатываю lol как мне нужно
    x += 1
    print("Обработано %d из %d" % (x, y), end="\n")

Но если вы хотите логировать свои сообщения, то лучше использовать библиотеку logging
import logging

import os

logger = logging.Logger('root')
logger.setLevel(os.getenv('LOGGING_LEVEL', 'INFO'))  # INFO, DEBUG
# Форматирование лога
log_formatter = logging.Formatter("%(asctime)s [%(threadName)s] [%(levelname)s] - %(message)s",
                                  datefmt='%Y-%m-%d %H:%M:%S')
# Уровень вывода
console_handler = logging.StreamHandler()
# Устанавливаем формат сообщений
console_handler.setFormatter(log_formatter)
logger.addHandler(console_handler)

x = 0
y = len('ololo')
for lol in 'ololo':
    # обрабатываю lol как мне нужно
    x += 1
    logger.info("Обработано %d из %d" % (x, y))

Вывод

2017-05-03 09:28:39 [MainThread] [INFO] - Обработано 1 из 5
2017-05-03 09:28:39 [MainThread] [INFO] - Обработано 2 из 5
2017-05-03 09:28:39 [MainThread] [INFO] - Обработано 3 из 5
2017-05-03 09:28:39 [MainThread] [INFO] - Обработано 4 из 5
2017-05-03 09:28:39 [MainThread] [INFO] - Обработано 5 из 5
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы