是否有一個函數或類能夠將lambda函數作爲參數並返回可以使用Pickle進行pickle的對象或函數?將lambda函數轉換爲pickleable對象
我想並行使用joblib.Parallel有一個lambda函數的問題,並將所有lambda函數轉換爲命名函數的代碼,使我的代碼看起來比以前更糟糕。
是否有一個函數或類能夠將lambda函數作爲參數並返回可以使用Pickle進行pickle的對象或函數?將lambda函數轉換爲pickleable對象
我想並行使用joblib.Parallel有一個lambda函數的問題,並將所有lambda函數轉換爲命名函數的代碼,使我的代碼看起來比以前更糟糕。
注意,酸洗的功能僅僅是泡菜它的名字和模塊的名稱定義它:
In [16]: import pickle
In [19]: def foo(x): return x+1
In [20]: pickle.dumps(foo)
Out[20]: 'c__main__\nfoo\np0\n.'
所以鹹菜功能你需要給它一個名字。取消該功能需要導入模塊。
如果將所有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
>>>
注意,還嵌套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
>>>
我知道有至少joblib
一個分支,使用dill
代替pickle
,這可能是爲什麼你問首先是pickle
。如果找不到分支,請使用與dill
相似的cloudpickle
,並且這也可能有效。
我沒有意識到有這樣的分支,我會研究一下! – BoZenKhaa
我試圖避免對代碼進行重大更改,除非絕對必要。我發現lambda函數非常有用,並且將它們命名並將它們移到不同的模塊中,這似乎是一個笨拙的解決方案。 – BoZenKhaa