Панель прогресса Python Модуль управления протоколом
Я видел различные решения для индикатора выполнения в Python, но простые решения stdout не работают для моего проекта. Я имею несколько классов и использую модуль "logging" для вывода информации в STDOUT. У меня есть функция, из которой я хочу показать индикатор выполнения на одной строке, каждый раз промывая буфер.
Пример простого хода:
for i in range(100):
time.sleep(1)
sys.stdout.write("\r%d%%" %i)
sys.stdout.flush()
Когда я пытаюсь писать через STDOUT, а затем очищать буфер, либо буфер не сбрасывается, либо прогресс никуда не идет. Я надеюсь избежать какой-либо нити или сложного процесса, чтобы сделать это возможным. Есть ли у кого-то предпочтительный способ сделать это?
Ответы
Ответ 1
Я не мог найти хорошее решение для этого, поэтому я написал просветить индикатор выполнения, чтобы справиться с этим. В основном это меняет область прокрутки терминала, поэтому регистрация выполняется над индикатором (ами) прогресса, а не перерисовывает индикатор (и) прогресса каждый раз, когда вы хотите записать в STDOUT. Это позволяет вам писать в терминал столько, сколько вы хотите, без необходимости вносить изменения в журналы, распечатывать и т.д.
import logging
import time
import enlighten
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger()
# Setup progress bar
manager = enlighten.get_manager()
pbar = manager.counter(total=100, desc='Ticks', unit='ticks')
for i in range(1, 101):
logger.info("Processing step %s" % i)
time.sleep(.2)
pbar.update()
Ответ 2
Я решил это так:
import logging
import time
from tqdm import tqdm
import io
class TqdmToLogger(io.StringIO):
"""
Output stream for TQDM which will output to logger module instead of
the StdOut.
"""
logger = None
level = None
buf = ''
def __init__(self,logger,level=None):
super(TqdmToLogger, self).__init__()
self.logger = logger
self.level = level or logging.INFO
def write(self,buf):
self.buf = buf.strip('\r\n\t ')
def flush(self):
self.logger.log(self.level, self.buf)
if __name__ == "__main__":
logging.basicConfig(format='%(asctime)s [%(levelname)-8s] %(message)s')
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
tqdm_out = TqdmToLogger(logger,level=logging.INFO)
for x in tqdm(range(100),file=tqdm_out,mininterval=30,):
time.sleep(.5)
Выход
2016-12-19 15:35:06 [INFO ] 16%|#####9 | 768/4928 [07:04<40:50, 1.70it/s]
2016-12-19 15:36:07 [INFO ] 18%|######6 | 865/4928 [08:04<40:34, 1.67it/s]
Ответ 3
Вы можете использовать tqdm progress bar с помощью настраиваемого обработчика посредством ведения журнала, как описано здесь:
import logging
import time
import colorlog
from tqdm import tqdm
class TqdmHandler(logging.StreamHandler):
def __init__(self):
logging.StreamHandler.__init__(self)
def emit(self, record):
msg = self.format(record)
tqdm.write(msg)
if __name__ == "__main__":
for x in tqdm(range(100)):
logger = colorlog.getLogger("MYAPP")
logger.setLevel(logging.DEBUG)
handler = TqdmHandler()
handler.setFormatter(colorlog.ColoredFormatter(
'%(log_color)s%(name)s | %(asctime)s | %(levelname)s | %(message)s',
datefmt='%Y-%d-%d %H:%M:%S',
log_colors={
'DEBUG': 'cyan',
'INFO': 'white',
'SUCCESS:': 'green',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'red,bg_white'},))
logger.addHandler(handler)
logger.debug("Inside subtask: "+str(x))
time.sleep(.5)
Ответ 4
Если вы знаете, индикатор выполнения всегда записывается в STDOUT, вы должны использовать print
вместо регистратора. См. Документацию в документации по документации по протоколу Python