如何将对象与可迭代对象一同传入executor.map?
解决executor.map中传递固定对象(如tarfile)与可迭代对象的问题
首先得明确一个核心点:如果你用的是ProcessPoolExecutor,直接传递tarfile对象是行不通的——因为进程间是完全隔离的,文件句柄这类资源没法被序列化传递到子进程里。这种情况下你应该改用ThreadPoolExecutor,线程共享同一个进程的资源,tarfile对象可以安全复用。
接下来,针对把固定的arc对象和可迭代的file_list一起传给executor.map,有两种常用的实现方式:
方法1:用functools.partial绑定固定参数
partial可以帮你把函数的某个参数预先固定住,这样executor.map只需要处理可迭代的文件列表就行:
import glob, os import tarfile import concurrent.futures from functools import partial def function(file1, arc): print(file1) # 建议用绝对路径,避免切换目录带来的路径混乱 arc.add(os.path.abspath(file1)) destination="/home/lol/org" src=["a","b"] for i in src: dir_path = os.path.join(destination,i) if not os.path.exists(dir_path): os.mkdir(dir_path) for i in src: tar_path = os.path.join(destination,i,f"{i}.tar") # 用with语句管理tarfile,自动释放资源 with tarfile.open(tar_path, 'w') as tFile: target_dir = os.path.join("/home",i) os.chdir(target_dir) file_list = glob.glob("*.txt") # 用partial绑定tFile到function的第二个参数 bound_func = partial(function, arc=tFile) # 使用ThreadPoolExecutor处理任务 with concurrent.futures.ThreadPoolExecutor() as executor: executor.map(bound_func, file_list)
方法2:用itertools.repeat生成重复的固定对象
itertools.repeat可以创建一个重复指定对象的可迭代器,刚好匹配executor.map多参数的传递逻辑:
import glob, os import tarfile import concurrent.futures from itertools import repeat def function(file1, arc): print(file1) arc.add(os.path.abspath(file1)) destination="/home/lol/org" src=["a","b"] for i in src: dir_path = os.path.join(destination,i) if not os.path.exists(dir_path): os.mkdir(dir_path) for i in src: tar_path = os.path.join(destination,i,f"{i}.tar") with tarfile.open(tar_path, 'w') as tFile: target_dir = os.path.join("/home",i) os.chdir(target_dir) file_list = glob.glob("*.txt") # 用repeat把tFile重复对应次数,和file_list的元素一一匹配 with concurrent.futures.ThreadPoolExecutor() as executor: executor.map(function, file_list, repeat(tFile, len(file_list)))
重要注意事项
- 线程池vs进程池:绝对不要用
ProcessPoolExecutor处理这类操作——子进程复制的tarfile句柄是无效的,跨进程修改同一个tar文件还可能导致数据损坏。线程池是唯一安全的选择。 - 路径规范:尽量使用绝对路径添加文件,避免切换工作目录后出现相对路径混乱的问题。
- 资源管理:用
with语句管理tarfile.open和ThreadPoolExecutor,能自动帮你释放资源,避免手动关闭遗漏导致的异常。
内容的提问来源于stack exchange,提问作者Varun Sudarshan
相关产品推荐
相关产品推荐

