使用concurrent.futures多进程后返回Future对象,如何改为返回列表?
解决ProcessPoolExecutor并行后返回Future对象导致下标错误的问题
问题原因
用ProcessPoolExecutor.submit()提交任务后,返回的是Future对象——这是异步任务的"占位符",不是实际的OCR识别结果,直接对它做下标访问(比如res1[0])会触发TypeError。
两种修改方案
方案1:调用Future对象的result()方法获取实际结果
通过result()方法阻塞等待任务完成,拿到真实的识别列表,再组装成原版本的元组结构:
from concurrent.futures import ProcessPoolExecutor # 假设你的OCR区域识别函数是这个 def ocr_area(area): # 这里是识别指定屏幕区域的逻辑,返回列表 ... def get_data(): # 定义三个需要识别的屏幕区域 area1 = (x1, y1, w1, h1) area2 = (x2, y2, w2, h2) area3 = (x3, y3, w3, h3) with ProcessPoolExecutor() as executor: # 提交三个识别任务,得到Future对象 future1 = executor.submit(ocr_area, area1) future2 = executor.submit(ocr_area, area2) future3 = executor.submit(ocr_area, area3) # 阻塞获取每个任务的实际结果 res1 = future1.result() res2 = future2.result() res3 = future3.result() # 返回和原版本一致的(列表1, 列表2, 列表3)元组 return (res1, res2, res3)
方案2:用executor.map()简化代码
如果三个识别任务逻辑一致,用map()可以直接按顺序获取所有结果,自动组装成迭代器,转成元组即可:
from concurrent.futures import ProcessPoolExecutor def ocr_area(area): ... def get_data(): areas = [(x1, y1, w1, h1), (x2, y2, w2, h2), (x3, y3, w3, h3)] with ProcessPoolExecutor() as executor: # map会按areas的顺序返回每个任务的结果 results = tuple(executor.map(ocr_area, areas)) # results就是三个列表组成的元组,和原版本返回格式完全一致 return results
注意事项
- 多进程要求
ocr_area函数及其依赖的所有对象(比如截图工具、OCR实例)必须能被序列化(pickle)。如果遇到序列化错误,可考虑换成ThreadPoolExecutor(适合IO密集型的OCR任务,同样能提升效率),或者调整代码让对象支持序列化。 - 可以给
result()加超时参数避免任务卡住,比如future1.result(timeout=10),超时会抛出TimeoutError。
内容的提问来源于stack exchange,提问作者Alexander Grenkov
相关产品推荐
相关产品推荐

