Поддержу тему прогресс-баров начатую на Хабре. Описанный там бар можно назвать "продакшн-баром". В свою очередь, поделюсь давно и удачно написанным "дебаг-баром". Основные его отличия в:
- возможности вывода дополнительной дебаг-инфы
- выводе времени обработки каждого шага
- поддержке стандартного питоньего logging-а
Используется он так:
from random import randint
from debugbar import cnt
data = range(10) # некоторые данные для обработки
cnt = Cnt(len(data), 2) # указываем размер данных и шаг счётчика
for d in data:
cnt.put('дополнительная инфа %s' % d) # выводим бар
time.sleep(randint(1, 3))
В результате получится что-то типа:
2 / 10 | 1.00 s. | дополнительная инфа 1
4 / 10 | 5.00 s. | дополнительная инфа 3
6 / 10 | 4.00 s. | дополнительная инфа 5
8 / 10 | 3.00 s. | дополнительная инфа 7
10 / 10 | 4.00 s. | дополнительная инфа 9
Вариант с использованием логгинга:
import logging
from random import randint
from debugbar import cnt
log = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG,
format='%(levelname)-8s %(message)s')
data = range(10) # некоторые данные для обработки
cnt = Cnt(len(data), 2)
for d in data:
cnt.put('дополнительная инфа %s' % d, log.info)
time.sleep(randint(1, 3))
Результат:
INFO 2 / 10 | 2.00 s. | дополнительная инфа 1
INFO 4 / 10 | 4.00 s. | дополнительная инфа 3
INFO 6 / 10 | 4.00 s. | дополнительная инфа 5
INFO 8 / 10 | 3.00 s. | дополнительная инфа 7
INFO 10 / 10 | 2.00 s. | дополнительная инфа 9
Ну и код самого модуля debugbar.py:
# -*- coding: utf-8 -*-
import sys
import time
from datetime import datetime, timedelta
class T:
'''Таймер'''
def __init__(self):
self.start = time.time()
def __str__(self):
sec = int(time.time() - self.start)
return '%2.2f s.' % sec if sec < 60 else str(timedelta(seconds=sec))
class Cnt:
'''Счётчик'''
timer_tpl = ' | %8s'
def __init__(self, limit, step=None, start=1, timer=True):
self.limit = limit
self.step = step if step else int(limit / 100) or 1
self.cnt = start
self.timer = timer
self.cnt_tpl = '%%%(cnt_len)si / %%%(cnt_len)si' % {
'cnt_len' : len(str(limit))}
if timer:
self.tm = T()
def put(self, msg='', log=None):
if not self.cnt % self.step or self.cnt == self.limit:
m = self.cnt_tpl % (self.cnt, self.limit)
if self.timer:
m += self.timer_tpl % self.tm
self.tm = T()
if msg:
m += ' | %s' % msg
if log:
log(m)
else:
print m
sys.stdout.flush()
if self.cnt < self.limit:
self.cnt += 1
0 коммент.:
Отправить комментарий