繁体   English   中英

如何正确地将生成器传递给 ThreadPoolExecutor Executor.map() 的 function 参数?

[英]How to correctly pass the generator to the function parameters of ThreadPoolExecutor Executor.map()?

在下面的程序中,我有两个问题要问。 第一个问题是,当我使用thread poolgenerator传递给function时,为什么在调用function之前需要遍历generator器? 第二个问题是如何使用正确的方法将generator传递给ThreadPoolExecutor Executor.map function。 下面程序遍历path目录下的文件后直接退出,不调用req function

我的最终目录是读取很多图片到base64编码,然后使用multiple threads发送HTTP requests并得到结果。 如果我使用的方法不是最有效的,请给我推荐一些高效且优秀的方法,在此先感谢

import json
import requests
import base64
import os
from itertools import repeat
from concurrent.futures.thread import ThreadPoolExecutor



def img_to_base64(img_path):
    for root, dirs, files in os.walk(img_path):
        for pic in files:
            if pic.endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif')):
                img = os.path.join(root, pic)
                with open(img, 'rb') as f:
                    bs64 = base64.b64encode(f.read()).decode('utf-8')
                yield img,bs64 

def req(host, img, bs64):
    url = f'http://{host}/demo/'
    body = {"requests": [
                    {
                        "resource": {
                            "base64": bs64
                        }
                    }
                ]
            }
    r = requests.post(url, data=json.dumps(body))
    print(img, r)


def run(host,path):
    base64s = img_to_base64(path)
    with ThreadPoolExecutor() as ex:
        ret = list(ex.map(req, repeat(host), base64s))
    return ret

if __name__ == '__main__':
    run('192.168.10.44','/data/')

所以 ThreadPoolExecutor map 方法需要一个可迭代

将生成器 object 传递给map遍历该可迭代对象。

有一种解决这种行为的方法,但它有点像一个 hacky 方法 - 从列表中调用该生成器方法,这将使您的执行程序接受作为生成器 object,而不是下一个产生的项目

base64s = [img_to_base64(path)]

编辑:

这不适用于诸如 List 之类的可变迭代器(例如,元组不会得到相同的结果)

这与我们在 python 中模拟指针的方式有关,RealPython 对此特定主题有很好的解释

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM