Using Pool map with a method of a class and a list
Joshua Landau
joshua at landau.ws
Wed Aug 7 07:53:40 EDT 2013
On 7 August 2013 11:10, Luca Cerone <luca.cerone at gmail.com> wrote:
> I can't try it now, I'll let you know later if it works!
> (Though just by reading I can't really understand what the code does).
Well,
>> from multiprocessing import Pool
>> from functools import partial
>>
>> class A(object):
>> def __init__(self,x):
>> self.value = x
>> def fun(self,x):
>> return self.value**x
This is all the same, as with
>> l = range(100)
>> p = Pool(4)
You then wanted to do:
> op = p.map(A(3).fun, l)
but bound methods can't be pickled, it seems.
However, A(3) *can* be pickled. So what we want is a function:
def proxy(arg):
A(3).fun(arg)
so we can write:
> op = p.map(proxy, l)
To generalise you might be tempted to write:
def generic_proxy(instance, name):
def proxy(arg):
# Equiv. of instance.name(arg)
getattr(instance, name)(arg)
but the inner function won't work as functions-in-functions can't be
pickled either.
So we use:
>> def _getattr_proxy_partialable(instance, name, arg):
>> return getattr(instance, name)(arg)
Which takes all instance, name and arg. Of course we only want our
function to take arg, so we partial it:
>> def getattr_proxy(instance, name):
>> """
>> A version of getattr that returns a proxy function that can
>> be pickled. Only function calls will work on the proxy.
>> """
>> return partial(_getattr_proxy_partialable, instance, name)
partial objects are picklable, btw.
>> op = p.map(getattr_proxy(A(3), "fun"), l)
>> print(op)
:)
More information about the Python-list
mailing list