【发布时间】:2012-02-17 22:59:43
【问题描述】:
我想在一个函数上使用装饰器,随后将其传递给多处理池。但是,代码失败并显示“PicklingError: Can't pickle : attribute lookup __builtin__.function failed”。我不太明白为什么它在这里失败。我确信这很简单,但我找不到。下面是一个最小的“工作”示例。我认为使用 functools 函数就足以让它工作。
如果我注释掉函数装饰,它可以正常工作。我在这里误解了multiprocessing 是什么?有什么办法可以做到这一点?
编辑:在添加可调用类装饰器和函数装饰器后,结果发现函数装饰器按预期工作。可调用的类装饰器继续失败。什么是可调用的类版本可以防止它被腌制?
import random
import multiprocessing
import functools
class my_decorator_class(object):
def __init__(self, target):
self.target = target
try:
functools.update_wrapper(self, target)
except:
pass
def __call__(self, elements):
f = []
for element in elements:
f.append(self.target([element])[0])
return f
def my_decorator_function(target):
@functools.wraps(target)
def inner(elements):
f = []
for element in elements:
f.append(target([element])[0])
return f
return inner
@my_decorator_function
def my_func(elements):
f = []
for element in elements:
f.append(sum(element))
return f
if __name__ == '__main__':
elements = [[random.randint(0, 9) for _ in range(5)] for _ in range(10)]
pool = multiprocessing.Pool(processes=4)
results = [pool.apply_async(my_func, ([e],)) for e in elements]
pool.close()
f = [r.get()[0] for r in results]
print(f)
【问题讨论】:
-
这篇文章似乎表明酸洗装饰物很棘手:gael-varoquaux.info/blog/?p=120
-
是的,我也找到了那个页面。这就是我添加
functools包装器的原因。但这似乎没有任何区别。我承认我真的不明白下面发生了什么,看看它为什么会失败。 -
如果有人还在寻找帖子,现在就在这里:gael-varoquaux.info/programming/…
标签: python decorator multiprocessing