[Python-Dev] multiprocessing not compatible with functional.partial

Neal Becker ndbecker2 at gmail.com
Thu Feb 12 16:53:56 CET 2009


Hrvoje Niksic wrote:

> Calvin Spealman wrote:
>> I don't think it would be unreasonable to consider either 1) making
>> functools.partial picklable (I don't know how feasible this is)
> 
> It's not only feasible, but quite easy and, I think, useful.  A
> "partial" instance is a simple triplet of (function, args, kwds), and it
> can be pickled as such.  For example:
> 
>  >>> import copy_reg, functools
>  >>> def _reconstruct_partial(f, args, kwds):
> ...     return functools.partial(f, *args, **(kwds or {}))
> ...
>  >>> def _reduce_partial(p):
> ...     return _reconstruct_partial, (p.func, p.args, p.keywords)
> ...
>  >>> copy_reg.pickle(functools.partial, _reduce_partial)
> 
> Test:
> 
>  >>> import operator, cPickle as cp
>  >>> p = functools.partial(operator.add, 3)
>  >>> p(10)
> 13
>  >>> cp.dumps(p)
> 
'c__main__\n_reconstruct_partial\np1\n(coperator\nadd\np2\n(I3\ntp3\nNtRp4\n.'
>  >>> p2 = cp.loads(_)
>  >>> p2(10)
> 13
> 
> Iedally this should be implemented in the functools.partial object itself.
Confirmed:

from multiprocessing import Pool

def power (x, pwr=2):
    return x**pwr

import functools
run_test = functools.partial (power, pwr=3)

import copy_reg, functools
def _reconstruct_partial(f, args, kwds):
    return functools.partial(f, *args, **(kwds or {}))

def _reduce_partial(p):
    return _reconstruct_partial, (p.func, p.args, p.keywords)

copy_reg.pickle(functools.partial, _reduce_partial)

if __name__ == "__main__":

    pool = Pool()
    cases = [3,4,5]
    results = pool.map (run_test, cases)
    print results

$python test_multi.py
[27, 64, 125]




More information about the Python-Dev mailing list