我有一个小脚本,可以执行一些简单的任务。运行Python 3.7。
其中一项任务是将一些文件合并在一起,这可能会花费一些时间。
它循环遍历多个目录,然后每个目录都传递给该函数。该功能仅循环遍历文件并将其合并。
而不是等待它完成一个目录,然后进入下一个目录,然后等待,然后进入下一个目录,等等...
我想利用功能/核心/线程使脚本一次将多个目录中的PDF合并在一起,这将节省时间。
我有这样的东西:
if multi_directories:
if os.path.isdir('merged'):
pass
else:
os.makedirs('merged')
for directory in multi_directories:
merge_pdfs(directory)
我的合并PDF功能如下:
def merge_pdfs(directory):
root_dir = os.path.dirname(os.path.abspath(__file__))
merged_dir_location = os.path.join(root_dir, 'merged')
dir_title = directory.rsplit('/', 1)[-1]
file_list = [file for file in os.listdir(directory)]
merger = PdfFileMerger()
for pdf in file_list:
file_to_open = os.path.join(directory, pdf)
merger.append(open(file_to_open, 'rb'))
file_to_save = os.path.join(
merged_dir_location,
dir_title+"-merged.pdf"
)
with open(file_to_save, "wb") as fout:
merger.write(fout)
return True
这很好用-但在目录中包含大量PDF的某些情况下,merge_pdfs
运行缓慢。
基本上-我希望能够遍历multi_directories
并为每个目录创建一个新线程或进程,并同时合并PDF。
我看过asyncio
,multithreading
以及无处不在的小片段,但似乎无法正常工作。
答案 0 :(得分:3)
您可以执行以下操作:
from multiprocessing import Pool
n_processes = 2
...
if multi_directories:
if os.path.isdir('merged'):
pass
else:
os.makedirs('merged')
pool = Pool(n_processes)
pool.map(merge_pdfs, multi_directories)
如果瓶颈是CPU使用率,应该会有所帮助。但是,如果瓶颈是HDD,可能会使情况变得更糟,因为从一个物理HDD并行读取多个文件通常比连续读取它们要慢。尝试使用不同值的 n_processes 。
顺便说一句,使用 list():file_list = list(os.listdir(directory))
来使列表可迭代。由于 listdir()返回 List ,因此您只需编写file_list = os.listdir(directory)