如何在我的主要功能中同时运行一个类?

时间:2019-11-21 13:21:31

标签: python class concurrent.futures

我想同时在我的main()函数中调用并运行一个类。 我想在代码中使用concurrent.futures同时运行不同的方法,但我发现可以将它们放在class中。

这是我到目前为止尝试过的:

import requests
import time
import concurrent.futures

img_urls = [
    'https://images.unsplash.com/photo-1516117172878-fd2c41f4a759',
    'https://images.unsplash.com/photo-1532009324734-20a7a5813719',
    'https://images.unsplash.com/photo-1524429656589-6633a470097c',
    'https://images.unsplash.com/photo-1530224264768-7ff8c1789d79'
]

t1 = time.perf_counter()


class Download:
    def __init__(self, img_url):
        self.img_url = img_url

    def download_image(self, img_url):
        img_bytes = requests.get(self.img_url).content
        return img_bytes

    def image_name(self, img_bytes):
        img_bytes = download_image(self, img_url)
        img_name = self.img_url.split('/')[3]
        img_name = f'{img_name}.jpg'
        with open(img_name, 'wb') as img_file:
            img_file.write(img_bytes)
            print(f'{img_name} was downloaded...')

    def run(self):
        download_image(self, img_url)
        image_name(self, img_bytes)


def main():
    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor.map(Download, img_urls)

if __name__ == "__main__":
    main()

t2 = time.perf_counter()

print(f'Finished in {t2-t1} seconds')

2 个答案:

答案 0 :(得分:1)

据我了解,您想同时执行不同Download对象的运行功能。

第一件事是run函数中存在语法错误,应该是:

def run(self):
    img_bytes = download_image(self, img_url)
    image_name(self, img_bytes)

否则未定义img_bytes

然后,您需要将正确的可调用对象传递给执行程序。如果您传递了Download类,它将仅创建它的一个实例,而不实际调用run方法。每次使用这样的新下载实例时都可以这样做:

executor.map(lambda url: Download(url).run, img_urls)

答案 1 :(得分:0)

解决此问题的一种方法是Marco提到的。

您要使用类进行调用和运行时,可以从__init__函数中调用多线程代码。

import requests
import time
import concurrent.futures

img_urls = [
    "https://images.unsplash.com/photo-1516117172878-fd2c41f4a759",
    "https://images.unsplash.com/photo-1532009324734-20a7a5813719",
    "https://images.unsplash.com/photo-1524429656589-6633a470097c",
    "https://images.unsplash.com/photo-1530224264768-7ff8c1789d79",
]

t1 = time.perf_counter()


class Download:
    def __init__(self, img_url):
        self.img_url = img_url
        self.download_all_images()

    def download_image(self, img_url):
        img_bytes = requests.get(img_url, stream=True).content
        return img_bytes

    def image_name(self, img_url):
        try:
            img_bytes = self.download_image(img_url)
            img_name = img_url.split("/")[3]
            img_name = f"{img_name}.jpg"
            print("here", img_name)
            with open(img_name, "wb") as img_file:
                img_file.write(img_bytes)
                print(f"{img_name} was downloaded...")
        except Exception as e:
            print(e)

    def download_all_images(self):
        try:
            with concurrent.futures.ThreadPoolExecutor() as executor:
                executor.map(self.image_name, self.img_url)
            return "Success"
        except:
            return "Failed"


def main():
    response = Download(img_urls)
    print(response)


if __name__ == "__main__":
    main()

t2 = time.perf_counter()

print(f"Finished in {t2 - t1} seconds")