简体   繁体   English

如何在我的主 function 中同时运行 class?

[英]How do I run a class concurrently in my main function?

I want to call and run a class in my main() function concurrently.我想同时在我的main() function 中调用并运行 class 。 I have different methods in my code that I want to run at the same time using concurrent.futures and I figured out I could put them in a class instead.我的代码中有不同的方法,我想使用concurrent.futures运行,我发现我可以将它们放在class中。

This is what I have tried so far:这是我到目前为止所尝试的:

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')

As I understand you want to execute the run function of different Download objects concurrently.据我了解,您想同时执行不同Download对象的运行 function 。

The first thing is that there is a syntax error in the run function, it should be:首先是运行function出现语法错误,应该是:

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

otherwise img_bytes isn't defined.否则img_bytes没有定义。

Then you need to pass the correct callable to the executor.然后您需要将正确的可调用对象传递给执行程序。 If you pass the class Download, it will only create an instance of it, not actually call the run method;如果你通过 class 下载,它只会创建它的一个实例,不会真正调用 run 方法; to do so with every time a new instance of Download something like this should work:每次下载类似这样的新实例应该工作时都这样做:

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

One way to solve this problem is as Marco mentioned.正如 Marco 所提到的,解决此问题的一种方法是。

As you want to call and run using class, you can call the multithreading code from the __init__ function.由于您想使用 class 调用和运行,您可以从__init__ function 调用多线程代码。

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")

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

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