Python 2.7 将lambda函数转换为可pickle对象

Python 2.7 将lambda函数转换为可pickle对象,python-2.7,lambda,pickle,Python 2.7,Lambda,Pickle,是否有一个函数或类能够将lambda函数作为参数并返回可以使用Pickle进行Pickle处理的对象或函数 我正在尝试使用joblib.Parallel对一些代码进行并行化,因为它的lambda函数有问题,将所有lambda函数转换为命名函数会使我的代码看起来比以前更糟糕 请注意,pickle函数只会pickle其名称和定义它的模块的名称: In [16]: import pickle In [19]: def foo(x): return x+1 In [20]: pickle.dumps

是否有一个函数或类能够将lambda函数作为参数并返回可以使用Pickle进行Pickle处理的对象或函数


我正在尝试使用joblib.Parallel对一些代码进行并行化,因为它的lambda函数有问题,将所有lambda函数转换为命名函数会使我的代码看起来比以前更糟糕

请注意,pickle函数只会pickle其名称和定义它的模块的名称:

In [16]: import pickle

In [19]: def foo(x): return x+1

In [20]: pickle.dumps(foo)
Out[20]: 'c__main__\nfoo\np0\n.'
因此,要pickle一个函数,需要给它一个名称。取消勾选函数需要导入模块


如果命名所有lambda函数“使代码看起来更糟”,那么可能将它们隐藏在单独的模块中,或者考虑如何对函数进行泛化以减少它们的数量。

您可以使用
dill
而不是
pickle
,后者知道如何序列化
lambda
,即使用作函数或类中的默认参数

>>> import dill
>>> 
>>> def doit(x, y=lambda x:x+1):
...   return y(x)
... 
>>> doit(3)
4
>>> _ = dill.dumps(doit)
>>> _
'\x80\x02cdill.dill\n_create_function\nq\x00(cdill.dill\n_load_type\nq\x01U\x08CodeTypeq\x02\x85q\x03Rq\x04(K\x02K\x02K\x02KCU\n|\x01\x00|\x00\x00\x83\x01\x00Sq\x05N\x85q\x06)U\x01xq\x07U\x01yq\x08\x86q\tU\x07<stdin>q\nU\x04doitq\x0bK\x01U\x02\x00\x01q\x0c))tq\rRq\x0ec__builtin__\n__main__\nh\x0bh\x00(h\x04(K\x01K\x01K\x02KCU\x08|\x00\x00d\x01\x00\x17Sq\x0fNK\x01\x86q\x10)h\x07\x85q\x11U\x07<stdin>q\x12U\x08<lambda>q\x13K\x01U\x00q\x14))tq\x15Rq\x16c__builtin__\n__main__\nh\x13NN}q\x17tq\x18Rq\x19\x85q\x1aN}q\x1btq\x1cRq\x1d.'
>>> didit = dill.loads(_)
>>> didit(3)
4
>>> 

我知道至少有一个
joblib
分支使用
dill
而不是
pickle
,这可能就是为什么您首先询问
pickle
。如果找不到分支,请查找带有
cloudpickle
的分支,它类似于
dill
,这也可能有效。

我不知道有这样的分支,我会调查它!除非绝对必要,否则我尽量避免对代码进行大的更改。我发现lambda函数非常有用,在我的情况下,命名它们并将它们移动到不同的模块似乎是一个笨拙的解决方案。
>>> f = lambda x: lambda y: x+y
>>> f(1)(2)
3
>>> dill.loads(dill.dumps(f))(1)(2)
3
>>> dill.loads(dill.dumps(f(1)))(2)
3
>>>