Python 3 concurrent.futures:如何在main函数中并行处理循环?
解决concurrent.futures中submit使用错误导致的TypeError问题
你遇到的TypeError: 'Future' object is not iterable错误,根源是对executor.submit()的用法理解有误,我来帮你拆解清楚并给出修改方案:
错误原因
executor.submit()是用来提交单个任务的方法,它执行后返回的是一个Future对象(代表这个异步任务的未来结果),而不是可迭代的任务结果集合。你直接用for out1 in executor.submit(range(0, 10))去遍历,自然会报错——因为Future对象不能被循环遍历。
而你最开始用的executor.map()是批量处理方法,它会自动把迭代器(比如range(0,10))里的每个元素传给目标函数,并行执行后返回可迭代的结果集合,这也是为什么最开始的代码能正常运行。
两种修改方案
根据你想在main()里直接处理循环的需求,有两种可行的修改方式:
方案1:用submit批量提交任务 + as_completed处理结果
如果你坚持要用submit,可以批量提交多个任务,然后通过concurrent.futures.as_completed()来获取每个完成任务的结果:
import concurrent.futures import threading def main(): output1 = list() with concurrent.futures.ThreadPoolExecutor() as executor: # 批量提交10个任务,每个任务对应range中的一个元素 # 这里用lambda把逻辑直接写在main里,也可以抽成内部函数 futures = [executor.submit(lambda x: 'Hello World\n', i) for i in range(0, 10)] # 遍历所有完成的异步任务,获取结果 for future in concurrent.futures.as_completed(futures): output1.append(future.result()) # 确认输出 print(output1) print("Task Executed {}".format(threading.current_thread())) if __name__ == '__main__': main()
方案2:用map + 内部函数(更简洁)
如果你的逻辑不复杂,其实可以把业务逻辑写成main()的内部函数,然后继续用executor.map(),这样既满足你“在main里处理”的需求,又保持代码简洁:
import concurrent.futures import threading def main(): # 把业务逻辑定义成main的内部函数 def process_task(i): return 'Hello World\n' output1 = list() with concurrent.futures.ThreadPoolExecutor() as executor: # 用map批量并行处理迭代器中的元素 for result in executor.map(process_task, range(0, 10)): output1.append(result) # 确认输出 print(output1) print("Task Executed {}".format(threading.current_thread())) if __name__ == '__main__': main()
核心总结
executor.submit(func, *args):提交单个任务,返回单个Future对象,需手动调用result()获取结果executor.map(func, iterable):批量处理迭代器中的元素,自动分发任务并返回可迭代的结果集合,无需手动管理Future
内容的提问来源于stack exchange,提问作者gdogg371
相关产品推荐
相关产品推荐

