我正在使用for循环遍历目录树中的一个大组文件。
在执行此操作时,我希望通过控制台中的进度条来监控进度。因此,我决定使用tqdm来实现此目的。
目前,我的代码如下所示:
for dirPath, subdirList, fileList in tqdm(os.walk(target_dir)):
sleep(0.01)
dirName = dirPath.split(os.path.sep)[-1]
for fname in fileList:
*****输出:
Scanning Directory....
43it [00:23, 11.24 it/s]所以,我的问题是它没有显示进度条。我想知道如何正确使用它,并更好地了解它的工作原理。此外,如果有任何其他替代tqdm,可以在这里使用。
发布于 2016-03-13 19:26:32
你不能显示完成的百分比,除非你知道“完成”是什么意思。
当os.walk运行时,它不知道它将迭代多少个文件和文件夹:os.walk的返回类型没有__len__。它必须一直向下查找目录树,枚举所有的文件和文件夹,以便对它们进行计数。换句话说,os.walk必须将所有工作做两次,才能告诉您它将生产多少个项目,这是低效的。
如果您决意要显示进度条,那么可以将数据放入内存中的列表中:list(os.walk(target_dir))。我不推荐这样做。如果你正在遍历一个大的目录树,这可能会消耗大量内存。更糟糕的是,如果followlinks为True,并且您有一个循环的目录结构(子目录链接到其父目录),那么它可能会一直循环下去,直到内存耗尽。
发布于 2016-05-15 09:34:11
作为explained in the documentation,这是因为您需要提供进度指示器。根据您对文件所做的操作,您可以使用文件数或文件大小。
其他答案建议将os.walk()生成器转换为列表,以便获得__len__属性。但是,根据您拥有的文件总数,这将耗费大量内存。
另一种可能是预计算:首先遍历整个文件树并计算文件总数(但不保留文件列表,只计算计数!),然后您可以再次遍历并向tqdm提供预先计算的文件数:
def walkdir(folder):
"""Walk through every files in a directory"""
for dirpath, dirs, files in os.walk(folder):
for filename in files:
yield os.path.abspath(os.path.join(dirpath, filename))
# Precomputing files count
filescount = 0
for _ in tqdm(walkdir(target_dir)):
filescount += 1
# Computing for real
for filepath in tqdm(walkdir(target_dir), total=filescount):
sleep(0.01)
# etc...请注意,我在os.walkdir上定义了一个包装器函数:由于您处理的是文件而不是目录,因此最好定义一个针对文件而不是目录的函数。
但是,您可以在不使用walkdir包装器的情况下获得相同的结果,但它会稍微复杂一些,因为您必须在遍历每个子文件夹之后恢复最后一个进度条状态:
# Precomputing
filescount = 0
for dirPath, subdirList, fileList in tqdm(os.walk(target_dir)):
filescount += len(filesList)
# Computing for real
last_state = 0
for dirPath, subdirList, fileList in os.walk(target_dir):
sleep(0.01)
dirName = dirPath.split(os.path.sep)[-1]
for fname in tqdm(fileList, total=filescount, initial=last_state):
# do whatever you want here...
# Update last state to resume the progress bar
last_state += len(fileList)发布于 2016-03-13 19:25:08
这是因为tqdm不知道os.walk的结果有多长,因为它是一个生成器,所以不能对其调用len。您可以通过首先将os.walk(target_dir)转换为列表来解决此问题:
for dirPath, subdirList, fileList in tqdm(list(os.walk(target_dir))):来自tdqm模块的文档:
如果可能的话,使用
len(可迭代)。作为最后的手段,只显示基本的进度统计信息(没有ETA,没有进度条)。
但是,len(os.walk(target_dir))是不可能的,所以没有预计时间或进度条。
正如本杰明所指出的,使用list确实会占用一些内存,但不会太多。在我的Windows10机器上,一个包含大约190,000个文件的假脱机目录导致Python使用了大约65MB的内存。
https://stackoverflow.com/questions/35969433
复制相似问题