如何序列化sympy lambdified函数?

aka*_*kai 8 python serialization numpy pickle sympy

标题说明了一切.有没有办法序列化sympy.lambdify生成的函数?:

import sympy as sym
import pickle
import dill
a, b = sym.symbols("a, b")
expr = sym.sin(a) + sym.cos(b)
lambdified_expr = sym.lambdify((a, b), expr, modules="numpy")
pickle.dumps(lambdified_expr) # won't work
dill.dumps(lambdified_expr) # won't work either
Run Code Online (Sandbox Code Playgroud)

...我想这样做的原因是因为我的代码生成了很多lambdified函数,但我发现它每次都需要很长时间.

Mik*_*rns 9

你实际上可以dill它来腌制它.dill(例如,在github上)的最新版本具有"设置",允许变体如何构建泡菜dump.是,dill此对象上的失败的默认设置,但如果您使用递归跟踪全局引用的设置(即recurse = True),则不会.此设置类似于cloudpickle默认情况下提供的设置.

>>> import sympy as sym
>>> import pickle
>>> import dill
>>> a, b = symbols("a, b")
>>> a, b = sym.symbols("a, b")
>>> expr = sym.sin(a) + sym.cos(b)
>>> lambdified_expr = sym.lambdify((a, b), expr, modules="numpy")
>>> 
>>> dill.settings
{'recurse': False, 'byref': False, 'protocol': 2, 'fmode': 0}
>>> dill.settings['recurse'] = True
>>> dill.dumps(lambdified_expr)
'\x80\x02cdill.dill\n_create_function\nq\x00(cdill.dill\n_unmarshal\nq\x01U\x83c\x02\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00C \x00\x00s\x14\x00\x00\x00t\x00\x00|\x00\x00\x83\x01\x00t\x01\x00|\x01\x00\x83\x01\x00\x17S(\x01\x00\x00\x00N(\x02\x00\x00\x00t\x03\x00\x00\x00sint\x03\x00\x00\x00cos(\x02\x00\x00\x00t\x01\x00\x00\x00at\x01\x00\x00\x00b(\x00\x00\x00\x00(\x00\x00\x00\x00s\x08\x00\x00\x00<string>t\x08\x00\x00\x00<lambda>\x01\x00\x00\x00s\x00\x00\x00\x00q\x02\x85q\x03Rq\x04}q\x05(U\x03cosq\x06cnumpy.core.umath\ncos\nq\x07U\x03sinq\x08cnumpy.core.umath\nsin\nq\tuU\x08<lambda>q\nNN}q\x0btq\x0cRq\r.'
Run Code Online (Sandbox Code Playgroud)

PS我是dill作者,所以我知道.

  • 因为`dill`可以序列化大范围的对象,`recurse = False`提供最广泛的覆盖范围.如果使用`recurse = True`,它对某些对象非常有效,但在许多情况下会中断序列化.如果(或何时)我解决它破坏的情况,那么它将成为默认情况.在此之前,最好的选择是*不*删除默认功能,但通过设置提供新功能.请参阅:https://github.com/uqfoundation/dill/issues/105 (2认同)
  • @Spiros:没错,你可以按每次通话设置它. (2认同)