【问题标题】:serialize / pickle a function that is defined in a string序列化/腌制在字符串中定义的函数
【发布时间】:2017-01-21 17:52:32
【问题描述】:

我想做以下事情:

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

我要解决的问题:我有一个字符串格式的函数,我需要能够序列化它(用于并行化目的。)

【问题讨论】:

  • 您应该解释您的代码中当前发生的不符合预期的情况。当该代码现在运行时会发生什么。你期望会发生什么。 究竟你想用你的代码实现什么?请修改如何组合一个更可靠的minimal reproducible example,以帮助更好地解决您的问题。
  • 感谢您的评论,我已添加错误消息。此外,我认为我很清楚地描述了我的问题。

标签: python serialization namespaces pickle dill


【解决方案1】:

我不确定为什么在你的问题中使用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
>>> 

【讨论】:

    【解决方案2】:

    你可以将当前的global命名空间传递给exec,然后你可以pickle函数:

    import pickle
    exec('def f(x): return x', globals())
    pickle.dumps(f)
    

    您是否可以在另一个环境中加载它,这是一个完全不同的问题,正如 here 所讨论的那样。

    【讨论】:

      【解决方案3】:

      不使用globals() 也可以:

      import pickle
      namespace = {}
      exec('def f(x): return x', namespace)
      f = namespace['f'] # has to have the same name
      pickle.dumps(f) 
      

      取自namespace的函数必须在函数命名空间中以相同的名称定义。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-23
        • 1970-01-01
        • 2019-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-18
        • 1970-01-01
        相关资源
        最近更新 更多