Я пытаюсь сделать индикатор выполнения при удалении файлов в python. Этот скрипт Python печатает количество файлов в каталоге, а затем удаляет их, показывая индикатор выполнения. При удалении 10 или 11 файлов все работает. Но когда количество файлов больше, например 20, Он показывает этот беспорядок,
Found 20 files.
Deleting[########################################################################################################
.........Deleting[###############################################################################################
##################Deleting[######################################################################################
###########################Deleting[#############################################################################
####################################Deleting[####################################################################
#############################################Deleting[###########################################################
######################################################Deleting[##################################################
#################################################################################################################
###############################################]100.0%
Но я хочу напечатать это так,
Found 20 files.
Deleting[####################.............]75%
Вот мой код,
import os
import sys
import time
out = sys.stdout
path_ = input("Enter the path: ")
count_ = 0
files = []
for path in os.listdir(path_):
if os.path.isfile(os.path.join(path_, path)):
count_ += 1
files.append(path)
print(f"Found {count_} files.")
hashes = ""
count = 0
hash = 0
spaces = ".." * 20
for item in files:
item = path_ + "\\" + item
os.remove(item)
count += 1
per = count/count_ * 100
for i in range(int(per)):
hash += 1
if hash == 10:
hash = 0
spaces = ".." * (count_ - count)
hashes += "##"
print("{}[{}{}]{}{}".format("Deleting", hashes, spaces, per, "%"), end='\r', file=out, flush=True)
time.sleep(1)
print("\n")
Что я здесь делаю неправильно? пожалуйста помоги.
Это сработало, спасибо. Но есть ли способ сделать это без tqdm?
Я обновил свой ответ до лучшей реализации, используя flush, поэтому вам больше не нужно беспокоиться об очистке консоли для обновлений.






Если вы предпочитаете не использовать tqdm, вот пример использования f-strings. Часть строки :-<{BAR_LEN} означает «заполнить оставшуюся часть строки до BAR_LEN символов (в данном случае 20) с помощью -».
from time import sleep
iterable = range(101) # this is the iterable you want to loop over
count = len(iterable) - 1
BAR_LEN = 20 # this is the length of your progress bar
for n in iterable:
# print the progress bar
# "#" is your fill character, '-' is your empty segment
print(
'\r',
f'Deleting[{"#" * round(n / (count / BAR_LEN)):-<{BAR_LEN}}]' # bar
f'{(n * 100) // count}%', # percentage
end='',
flush=True,
)
sleep(0.2) # optional - just simulates something happening in the background
Я нашел то, что работает для меня, надеюсь, что комментарии сделают это понятным.
Это решение не использует os.system для очистки напечатанных строк, поэтому оно должно работать в вашей среде IDE.
Тем не менее, я настоятельно рекомендую изучить tqdm, так как он очень прост в использовании и оптимизирован. для такого рода вещей.
Не стесняйтесь задавать дополнительные вопросы, если это необходимо. Не забудьте принять ответ, если он решил вашу проблему!
import os
import sys
import time
out = sys.stdout
path_ = input("Enter the path: ")
count_ = 0
files = []
for path in os.listdir(path_):
if os.path.isfile(os.path.join(path_, path)):
count_ += 1
files.append(path)
print(f"Found {count_} files.")
count = 0
hash_counter = 0
#avoid creating a variable named 'hash', as it is a method name.
spaces = ".." * 20
for item in files:
item = path_ + "\\" + item
os.remove(item)
count += 1
per = count/count_ * 100
is_last_file = (count==count_)
#this variable checks if the number of deleted files (count) si equal to the total number of files (count_),
#so it will return True only when we're deleting the last file of the directory.
for i in range(int(per)):
hash += 1
if hash == 10:
hash = 0
number_of_hashes = int(round(per/5, 0))
#first we calculate the number of hashes ("##") in our progress bar.
#we divide the percentage by five because we have a percentage x/100 but we want to display it on a divider of 20 (x/20),
#so we divide your percentage by 5 (e.g 40% of 20 = 5 hashes)
hashes = "##" * number_of_hashes
spaces = ".." * (20-number_of_hashes)
#we calculate easily the number of spaces : it's 20 (the size of our progress bar) minus the number of hashes.
print(f"{'Deleting' if not is_last_file else 'Deleted'} [{hashes}{spaces}] {per:.1f}%", end=('\r' if not is_last_file else '\n'), file=out, flush=True)
#using f-strings here is more pythonic ! ;)
#Also as you can see i used ":.1f" after the percentage. this way we have only one decimal after our float.
time.sleep(1)
#you can remove this from your code afterwards.
print("\n")
@ ΞένηΓήινος Извините, если мой английский очень простой, так как я не носитель языка, но нет, мой ответ был сделан вручную. Я понимаю, что небольшое количество изменений, которые вносит мой код, подозрительно, но я хотел сохранить как можно больше кода OP в своем ответе.
Смотрите это.
Я пытался сделать его лучше, но все равно ИИ не использовался.
Как я уже сказал, я старался сохранить как можно больше кода OP. Я знаю, что этот код очень неоптимизирован, но он не мой.
@diogeek, ты в порядке, это не было написано ИИ. Поместите пост в undetectable.ai/?via=36ovg&fp_sid=aicheck, чтобы убедиться в этом.
Основная проблема заключается в вашем внутреннем цикле for.
Во-первых, поскольку вы не сбрасываете hashes, он пересчитывает необходимое количество хэшей. Например. при 10% он добавляет два хэша, а затем при 20% он считает как 10%, так и 20% и добавляет четыре дополнительных хэша, всего шесть хэшей. Я не верю, что ты намереваешься это сделать.
Во-вторых, я не думаю, что hash тоже считается так, как вы хотите. Например, при удалении одного файла из 20 (5%) хэш становится равным 5. Затем при удалении второго файла (10%) хэш возобновляет приращение с 5 и сбрасывается на полпути и заканчивается на 5.
hash является ключевым словом и не переназначайте его. Ваш код очень неэффективен и неэлегантен.
Я рефакторил ваш код.
import os
from collections import deque
def cyan(text):
return f'\x1b[36m{text}\x1b[0m'
def recur_dir(folder, path):
files = deque()
for entry in os.scandir(folder):
if entry.is_file():
files.append(f'{path}/{entry.name}')
elif entry.is_dir():
files.extend(recur_dir(entry, f'{path}/{entry.name}'))
return files
def delete(folder):
files = recur_dir(folder, folder)
total = len(files)
for i, file in enumerate(files, start=1):
os.remove(file)
progress = i/total*100
print(f"\rDeleting[{cyan('█' * round(progress)):·<109}] {progress:.2f}%", end='', flush=True)
Используйте так: delete('path/to/folder').
Индикатор:
Deleting[██████████████████████████████████████████████████████████████······································] 61.97%
С цветом:


Обратите внимание, что путь к папке не может заканчиваться на '/'.
Чтобы получить все файлы, вы можете использовать простую рекурсивную функцию. Ваш код не перечисляет все файлы в данном каталоге рекурсивно, то есть он не будет удалять файлы внутри подкаталогов данной папки.
Мой код рекурсивно перечисляет все файлы внутри данного каталога.
Чтобы получить количество элементов внутри коллекции, просто используйте len(lst). Вам не нужно многократно увеличивать переменную вручную.
Затем вы можете использовать перечисление для расчета прогресса, прогресс - это просто общее количество, деленное на индекс (если вы используете индексирование на основе одного). Это так просто.
Это магическое число должно быть 109, а не 100, потому что после раскрашивания текста строка будет содержать коды ANSI, коды ANSI не будут напечатаны, вместо этого они изменят цвет текста, но они все равно будут считаться символами. при вычислении длины, и на них приходится 9 дополнительных символов.
Знак «меньше» указывает, что строка должна быть выровнена по левому краю, так как есть 9 дополнительных символов, полоса прогресса будет иметь длину только 91 символ, пока прогресс не достигнет 91%, потому что вам нужен только 91 символ для левого дополнения до 100 символов. Таким образом, использование 109 сделает индикатор выполнения всегда длиной 100 символов.
Пожалуйста, не говорите "спасибо" в комментариях. Вместо этого вы должны сказать «спасибо», нажав большую кнопку с галочкой, чтобы принять полезные ответы.
Использование формата f-строки. Это удалит быстрее. Он может удалить более 20 файлов.
Измените это в строке 31:
print("{}[{}{}]{}{}".format("Deleting", hashes, spaces, per, "%"), end='\r', file=out, flush=True)
к:
print(f"Deleting {hashes} {spaces}, {per}% \r", file=out, flush=True)
Выход: Найдено 10 файлов. Удаление ## .................., 10,0%
Deleting ###### ................, 20.0%
Deleting ############ .............., 30.0%
Deleting #################### ............, 40.0%
Deleting ############################## .........., 50.0%
Deleting ########################################## ........, 60.0%
Deleting ######################################################## ......, 70.0%
Deleting ######################################################################## ...., 80.0%
Deleting ########################################################################################## .., 90.0%
Deleting ############################################################################################################## , 100.0%
Другое это удаление жесткое.
print(f"Deleting {spaces} {per}% \r", file=out, flush=True)
Выход:
Found 20 files.
Deleting ........................................ 5.0%
Deleting .................................... 10.0%
Deleting .................................. 15.0%
Deleting ................................ 20.0%
Deleting .............................. 25.0%
Deleting ............................ 30.0%
Deleting .......................... 35.0%
Deleting ........................ 40.0%
Deleting ...................... 45.0%
Deleting .................... 50.0%
Deleting .................. 55.00000000000001%
Deleting ................ 60.0%
Deleting .............. 65.0%
Deleting ............ 70.0%
Deleting .......... 75.0%
Deleting ........ 80.0%
Deleting ...... 85.0%
Deleting .... 90.0%
Deleting .. 95.0%
Deleting 100.0%
Я предлагаю заглянуть в tqdm - он специально создан для таких вещей.