序列化/腌制一个在字符串中定义的函数
serialize / pickle a function that is defined in a string
我想做以下事情:
import pickle
namespace = {}
exec('def f(x): return x', namespace)
pickle.dumps(namespace['f'])
但是,这会导致以下错误:
---------------------------------------------------------------------------
PicklingError Traceback (most recent call last)
<ipython-input-102-61493bb3c732> in <module>()
2 namespace = {}
3 exec('def f(x): return x', namespace)
----> 4 pickle.dumps(namespace['f'])
PicklingError: Can't pickle <function f at 0x7f2134171950>: it's not the same object as __main__.f
我想解决的问题:我有一个字符串格式的函数,我需要能够序列化它(为了并行化目的。)
您可以将当前的 global
命名空间传递给 exec,然后您可以 pickle 函数:
import pickle
exec('def f(x): return x', globals())
pickle.dumps(f)
您是否可以在另一个环境中加载它,这是一个与 here 讨论完全不同的问题。
在不使用 globals()
的情况下,以下内容也有效:
import pickle
namespace = {}
exec('def f(x): return x', namespace)
f = namespace['f'] # has to have the same name
pickle.dumps(f)
取自 namespace
的函数必须在同名的函数命名空间中定义。
我不确定为什么在你的问题中使用了 dill
标签,因为你只使用了 pickle
... 但是如果你真的需要你的代码是你写的,请注意,您可以将 pickle
替换为 dill
... 它有效:
>>> import dill as pickle
>>> namespace = {}
>>> exec('def f(x): return x', namespace)
>>> _f = pickle.dumps(namespace['f'])
>>> _f
'\x80\x02cdill.dill\n_create_function\nq\x00(cdill.dill\n_load_type\nq\x01U\x08CodeTypeq\x02\x85q\x03Rq\x04(K\x01K\x01K\x01KCU\x04|\x00\x00Sq\x05N\x85q\x06)U\x01xq\x07\x85q\x08U\x08<string>q\tU\x01fq\nK\x01U\x00q\x0b))tq\x0cRq\r}q\x0e(U\x0c__builtins__q\x0fc__builtin__\n__dict__\nh\nh\x00(h\rh\x0eh\nNN}q\x10tq\x11Rq\x12uh\nNNh\x10tq\x13R0h\x12.'
>>> f = pickle.loads(_f)
>>> f(5)
5
>>>
我想做以下事情:
import pickle
namespace = {}
exec('def f(x): return x', namespace)
pickle.dumps(namespace['f'])
但是,这会导致以下错误:
---------------------------------------------------------------------------
PicklingError Traceback (most recent call last)
<ipython-input-102-61493bb3c732> in <module>()
2 namespace = {}
3 exec('def f(x): return x', namespace)
----> 4 pickle.dumps(namespace['f'])
PicklingError: Can't pickle <function f at 0x7f2134171950>: it's not the same object as __main__.f
我想解决的问题:我有一个字符串格式的函数,我需要能够序列化它(为了并行化目的。)
您可以将当前的 global
命名空间传递给 exec,然后您可以 pickle 函数:
import pickle
exec('def f(x): return x', globals())
pickle.dumps(f)
您是否可以在另一个环境中加载它,这是一个与 here 讨论完全不同的问题。
在不使用 globals()
的情况下,以下内容也有效:
import pickle
namespace = {}
exec('def f(x): return x', namespace)
f = namespace['f'] # has to have the same name
pickle.dumps(f)
取自 namespace
的函数必须在同名的函数命名空间中定义。
我不确定为什么在你的问题中使用了 dill
标签,因为你只使用了 pickle
... 但是如果你真的需要你的代码是你写的,请注意,您可以将 pickle
替换为 dill
... 它有效:
>>> import dill as pickle
>>> namespace = {}
>>> exec('def f(x): return x', namespace)
>>> _f = pickle.dumps(namespace['f'])
>>> _f
'\x80\x02cdill.dill\n_create_function\nq\x00(cdill.dill\n_load_type\nq\x01U\x08CodeTypeq\x02\x85q\x03Rq\x04(K\x01K\x01K\x01KCU\x04|\x00\x00Sq\x05N\x85q\x06)U\x01xq\x07\x85q\x08U\x08<string>q\tU\x01fq\nK\x01U\x00q\x0b))tq\x0cRq\r}q\x0e(U\x0c__builtins__q\x0fc__builtin__\n__dict__\nh\nh\x00(h\rh\x0eh\nNN}q\x10tq\x11Rq\x12uh\nNNh\x10tq\x13R0h\x12.'
>>> f = pickle.loads(_f)
>>> f(5)
5
>>>