【问题标题】:Convert lambda function into pickleable object将 lambda 函数转换为 pickleable 对象
【发布时间】:2016-01-06 14:54:13
【问题描述】:

是否有一个函数或类能够将 lambda 函数作为参数并返回可以使用 Pickle 腌制的对象或函数?

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

【问题讨论】:

    标签: python-2.7 lambda pickle


    【解决方案1】:

    请注意,对函数进行腌制只会腌制其名称和定义它的模块的名称

    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 函数“让代码看起来更糟”,那么也许将它们隐藏在一个单独的模块中,或者考虑如何泛化函数以减少它们的数量。

    【讨论】:

    • 除非绝对必要,否则我会尽量避免对代码进行大的更改。我发现 lambda 函数非常有用,并且在我的情况下命名所有函数并将它们移动到不同的模块似乎是一个笨拙的解决方案。
    【解决方案2】:

    您可以使用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 的原因。如果找不到分支,请查找带有cloudpickle 的分支,与dill 类似,这也可能有效。

    【讨论】:

    • 我没有意识到有这样的分支,我会调查一下!
    猜你喜欢
    • 2022-01-16
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多