Python Многопроцессорная обработка для вызова функции класса - PullRequest
1 голос
/ 27 февраля 2020

Я пытаюсь мультипроцессировать большое количество объектов, которые мне нужны для вызова функции класса off. Я не могу вытащить функцию за пределы класса, поэтому мне просто нужно найти способ ускорить вызов этой функции.

Заранее большое спасибо

import time

# - Bespoke Class that is standalone - #
class sub_class:
    def __init__(self, item_id, assumptions = "BlahBlahBlah"):
        self.item_id = item_id
        self.assumptions = assumptions
        self.test_count = 0

    def some_func(self, adder=1):
        self.test_count += adder
        time.sleep(0.1)


# - initialise a list of classes - #
item_ids = ['A', 'B', 'C', 'D']
items = [sub_class(_id) for _id in item_ids]

print( sum(_item.test_count for _item in items) )
# Prints out 0

# - invoke a class level function - #
[_item.some_func(adder=2) for _item in items]

print( sum(_item.test_count for _item in items) )
# Prints out 8

1 Ответ

1 голос
/ 27 февраля 2020

Это работает только с небольшим изменением some_fun c ().

import time
from concurrent.futures import ProcessPoolExecutor, wait, ALL_COMPLETED


# - Bespoke Class that is standalone - #
class MyClass:
    def __init__(self, item_id, assumptions="BlahBlahBlah"):
        self.item_id = item_id
        self.assumptions = assumptions
        self.test_count = 0

    def some_func(self, adder=1):
        self.test_count += adder
        print(f"{self.item_id} executing some_func()")
        time.sleep(0.1)
        # note: we must return ourselves
        return self


# Don't omit this on Windows
if __name__ == '__main__':

    # - initialise a list of classes - #
    item_ids = ['A', 'B', 'C', 'D']
    items = [MyClass(item_id) for item_id in item_ids]

    print(sum(item.test_count for item in items))
    # Prints out 0

    # - invoke a class level function - #
    with ProcessPoolExecutor(max_workers=4) as executor:
        future_list = []
        for item in items:
            future_list.append(executor.submit(item.some_func, adder=2))

        wait(future_list, return_when=ALL_COMPLETED)

        # note: we must use the returned self to get the test count
        print(sum(future.result().test_count for future in future_list))
        # Prints out 8

        # note: the original items haven't changed
        print(sum(item.test_count for item in items))
        # Prints out 0

«Элементы» копируются в новый процесс, поэтому вместо них необходимо использовать будущие значения return (). Следовательно, вы можете заменить оригинальные элементы, используя items = [future.result() for future in future_list] в некоторый момент после wait().

...