我如何更改此代码以使每个文件都显示进度条并且迭代是每个循环?

How can I change this code to make the progress bars appear for each file and the iteration be each loop?

我正在努力让 tqdm 的进度条保持和更新,而不是写入新行。注意:我正在使用 multiprocessing 来并行化我的代码,而 tqdm 在我正在并行化的函数内部。

我添加了一个 print 语句,因此当 运行 程序运行时,文件将全部出现在我的终端中。下面的可重现示例:

import multiprocessing
import time

from tqdm import tqdm
from joblib import Parallel, delayed


def run_file_analysis(text):
    cool = []
    for i in tqdm(range(0, 10), position = 0, leave = True, desc = f'Text : {text}'):
        print('')
        cool.append(i)
        time.sleep(1)

num_cores = multiprocessing.cpu_count()
ls = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']

if __name__ == "__main__":
    processed_list = Parallel(n_jobs=num_cores)(delayed(run_file_analysis)(i) for i in ls)

当前输出:

所需的输出将是十个文本对象 - 1、2、3、...、10 以及每个对象对应的更新进度条。不是 100 个不同的。我尝试关注许多与 tqdmmultiprocessing 集成主题相关的 Whosebug 问题,但其中 none 和我希望的一样简单。任何帮助,将不胜感激。

正如评论中已经讨论的那样,您不想在 print 语句中添加额外的新行。 相反,您想在 tqdm 中使用位置参数。 docs.

中甚至提到了不同线程的用例
position : int, optional
  Specify the line offset to print this bar (starting from 0)
  Automatic if unspecified. Useful to manage multiple bars at once (eg, from threads).

目前这个参数设置为0,所以每次new都会启动进度条。相反,您想使用线程数。由于简单,您可以将给定的文本转换为整数并使用它。但是不推荐用于生产。

import multiprocessing
import time

from tqdm import tqdm
from joblib import Parallel, delayed


def run_file_analysis(text):
    cool = []
    for i in tqdm(range(0, 10), position=int(text), leave=True, desc = f'Text : {text}'):
        cool.append(i)
        time.sleep(1)

num_cores = multiprocessing.cpu_count()
ls = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']

if __name__ == "__main__":
    processed_list = Parallel(n_jobs=num_cores)(delayed(run_file_analysis)(i) for i in ls)

如果文本不能直接转换为整数,可以使用'enumerate'并将索引传递给函数。

import multiprocessing
import time

from tqdm import tqdm
from joblib import Parallel, delayed


def run_file_analysis(text, job_number):
    cool = []
    for i in tqdm(range(0, 10), position=job_number, leave=True, desc = f'Text : {text}'):
        cool.append(i)
        time.sleep(1)

num_cores = multiprocessing.cpu_count()
ls = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']

if __name__ == "__main__":
    processed_list = Parallel(n_jobs=num_cores)(delayed(run_file_analysis)(text, i) for i, text in enumerate(ls))

编辑:

可以通过将 prefer='threads' 设置为并行构造函数来减少某些竞争条件:

if __name__ == "__main__":
    processed_list = Parallel(n_jobs=num_cores, prefer="threads")(delayed(run_file_analysis)(text, i) for i, text in enumerate(ls))