Как исправить или реорганизовать этот шаблон многопроцессорной обработки, чтобы избежать ошибок травления? - PullRequest
0 голосов
/ 29 апреля 2020

Еще один вопрос травления ... Следующее приводит к ошибкам травления. Я думаю, что это связано со сферой или чем-то подобным. Я еще не уверен.

Цель состоит в том, чтобы иметь декоратор, который принимает аргументы и обогащает функцию методами. Если лучший способ - просто создать классы явно, то это нормально, но это предназначено для того, чтобы скрывать вещи от пользователей, пишущих «контент».

import concurrent.futures
import functools

class A():
    def __init__(self, fun, **kwargs):
        self.fun = fun
        self.stuff = kwargs
        functools.update_wrapper(self, fun)
    def __call__(self, *args, **kwargs):
        print(self.stuff, args, kwargs)
        return self.fun(*args, **kwargs)

def decorator(**kwargs):
    def inner(fun):
        return A(fun, **kwargs)
    return inner

@decorator(a=1, b=2)
def f():
    print('f called')

executor = concurrent.futures.ProcessPoolExecutor(max_workers=10)

tasks = [f for x in range(10)]
fut = list()
for task in tasks:
    fut.append(executor.submit(task))
res = [x.result() for x in fut]
print(res)

Ошибка:

_pickle.PicklingError: Can't pickle <function f at 0x7fe37da121e0>: it's not the same object as __main__.f

1 Ответ

1 голос
/ 04 мая 2020

Я закончил тем, что сделал что-то вроде этого:

def dill_wrapped(dilled, *args, **kwargs):
    fun = dill.loads(dilled)
    return wrapped(fun, *args, **kwargs)

Вероятно, вам следует стараться избегать этого, но иногда вам это действительно нужно при украшении функций.

...