Pull to refresh

Comments 11

Я бы упомянул ascii-последовательности хотя бы как дань истории :)


Конечно, прикольно взять готовое и прикрутить в два щелчка… но на самом деле индикатор прогресса можно запилить самому и это достаточно просто.


Что-то вроде такого у меня сейчас вышло:


from time import sleep
from sys import stdout

JUMP_LEFT_SEQ = '\u001b[100D'
DELAY = 0.05

def loading():
    for i in range(0, 127):
        sleep(DELAY)
        print(JUMP_LEFT_SEQ, end='')
        print(f'Progress: {i:0>3}%', end='')
        stdout.flush()
    print()

loading()
Ещё можно в стиле ninja build:
class ProgressBar:
    def __init__(self, total):
        self.total = total
        self.current = 0
        self.prev_len = 0

    def next(self, string):
        self._clear()

        self.current += 1
        assert self.current <= self.total, 'Incorrect total task count'

        current_string = '[{}/{}] {}'.format(self.current, self.total, string)
        self.prev_len = len(current_string)
        print(current_string, end='', flush=True)

    def _clear(self):
        import sys

        if self.current == 0:
            return

        if sys.__stdout__.isatty():
            print('\r', end='')
            print(' ' * self.prev_len, end='')
            print('\r', end='')
        else:
            print('')
Спасибо за статью.
Хорошо бы еще упомянуть, как его не выводить, если скрипт запущен не в интерактивном режиме (например в пайплайне), иначе сильно замусоривается лог выполнения.
По моему опыту это зависит от библиотеки: например в tqdm есть аргумент disable, при значении True которого прогресс бар не рисуется.

Посмотрите ещё progress из click от Армина.


with click.progressbar(length=total_size,
                       label='Unzipping archive') as bar:
    for archive in zip_file:
        archive.extract()
        bar.update(archive.size)

Как по мне, так какое-то странное извращение — в cli-тулзы тащить гуевые компоненты для индикации прогресса.

В статье не упомянуто, что прогресс-индикатор удобно всегда иметь в конце вывода, чтобы всегда логи писались перед ним. progressbar позволяет это делать так:

import progressbar
progressbar.streams.wrap_stderr()  # Wrapping the bar around logs
logging.basicConfig()


Таким образом, консоль не замусоривается.
Sign up to leave a comment.

Articles