Вывод в stdout отличается в cmd и консоли Python - PullRequest
0 голосов
/ 24 мая 2019

Я новичок в Python и работаю над небольшой программой, которая копирует все файлы с заданным расширением из папки и ее подпапок в другой каталог. Недавно я добавил простой индикатор выполнения и счетчик оставшихся файлов. Проблема в том, что, когда я запускаю его из cmd, а счетчик приходит, скажем, от 1000 до 999 cmd добавляет ноль вместо последней цифры вместо пробела. Более того, после завершения программы счетчик оставшихся файлов должен быть заменен словом «Готово». и это также не работает хорошо.

Я пытался заменить sys.stdout.write на print и пытался не использовать f-строки, результат тот же.

def show_progress_bar(total, counter=0, length=80):
    percent = round(100 * (counter / total))
    filled_length = int(length * counter // total)
    bar = '=' * filled_length + '-' * (length - filled_length)
    if counter < total:
        suffix = f'Files left: {total - counter}'
    else:
        suffix = 'Done.'
    sys.stdout.write(f'\rProgress: |{bar}| {percent}% {suffix}')
    sys.stdout.flush()

def selective_copy(source, destination, extension):
    global counter
    show_progress_bar(total)
    for foldername, subfolders, filenames in os.walk(source):
        for filename in filenames:
            if filename.endswith(extension):
                if not os.path.exists(os.path.join(destination, filename)):
                    shutil.copy(os.path.join(foldername, filename), os.path.join(destination, filename))
                else:
                    new_filename = f'{os.path.basename(foldername)}_{filename}'
                    shutil.copy(os.path.join(foldername, filename), os.path.join(destination, new_filename))
                counter += 1
                show_progress_bar(total, counter)

Я ожидал, что вывод в cmd будет таким же, как в консоли, а именно: Запуск программы:

Progress: |=========-----------------------------------------------------------------------| 12% Files left: 976

Программа завершена:

Progress: |================================================================================| 100% Done.

Но в CMD я получил это: Запуск программы:

Progress: |=========-----------------------------------------------------------------------| 12% Files left: 9760

Программа завершена:

Progress: |================================================================================| 100% Done. left: 100

1 Ответ

1 голос
/ 24 мая 2019

Как правило, печать «\ r» вернет курсор в начало строки, но не сотрет ничего уже написанного. Поэтому, если вы напишите «1000», а затем «\ r» и «999», последние 0 из «1000» все равно будут видны.

(Я не уверен, почему этого не происходит в вашей консоли Python. Возможно, он интерпретирует «\ r» по-другому. Трудно сказать, не зная точно, какое программное обеспечение вы используете.)

Одним из решений является печать нескольких пробелов после вывода, чтобы гарантировать, что слегка более длинные старые сообщения будут перезаписаны. Вероятно, вы можете использовать только один пробел для суффикса «Осталось файлов:», поскольку он уменьшается не более чем на один символ, но суффиксу «готово» потребуется больше.

if counter < total:
    suffix = f'Files left: {total - counter} '
else:
    suffix = 'Done.               '
...