【问题标题】:How to pickle function from imported module with dill如何使用 dill 从导入的模块中提取函数
【发布时间】:2021-06-05 00:20:37
【问题描述】:

我正在尝试用莳萝腌制功能。我想包含整个函数,而不仅仅是对它的引用。这是我的两个文件:

fun.py:

import dill
from foo import ppp

def qqq(me):
    return me + 1

print(dill.dumps(ppp, protocol=4, recurse=True, byref=True))
print(dill.dumps(qqq, protocol=4, recurse=True, byref=True))

还有 foo.py

def qqq(me):
    return me + 1

当我运行 fun.py 时,我得到以下输出:

b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00\x8c\x03foo\x94\x8c\x03ppp\x94\x93\x94.'
b'\x80\x04\x95\x90\x00\x00\x00\x00\x00\x00\x00\x8c\ndill._dill\x94\x8c\x10_create_function\x94\x93\x94(h\x00\x8c\n_load_type\x94\x93\x94\x8c\x08CodeType\x94\x85\x94R\x94(K\x01K\x00K\x01K\x02KCC\x08|\x00d\x01\x17\x00S\x00\x94NK\x01\x86\x94)\x8c\x02me\x94\x85\x94\x8c\x06fun.py\x94\x8c\x03qqq\x94K\x04C\x02\x00\x01\x94))t\x94R\x94}\x94h\rNN}\x94Nt\x94R\x94.'

我希望能够让输出的第一行和第二行更相似,并且在以后重新加载时实际上封装了函数而不需要上下文。有没有办法做到这一点?

非常感谢! 詹姆斯

【问题讨论】:

    标签: pickle dill


    【解决方案1】:

    如果模块 (foo) 安装在两台计算机上,那么除了导入函数之外不需要做任何事情。因此,我假设问题与仅安装在第一台机器上的模块有关。

    这还取决于模块foo 是“安装”在sys.path 上还是仅在当前目录中可用。看: https://github.com/uqfoundation/dill/issues/123

    如果它只在当前目录中可用,要么使用dill 来pickle 文件本身,要么使用dill.source.getsource 之类的东西将模块的源代码提取为字符串,然后将字符串作为“pickle”传输(这就是ppft 所做的)。

    不过,通常dill 通过引用来腌制导入的函数,因此假定它们在load/dump 的两侧都可用。

    【讨论】:

    • 我认为 dill.source.getsource 是我想要的!我想创建源代码(或传输到远程机器的任何内容)的哈希,以便我可以根据指令确定性地将输出缓存在某个位置。谢谢!
    • 你知道服务端需要调用什么函数来执行getsource输出的源码吗?
    • 如果我没记错的话,dill.source.importable 使用getsource 来获取一个可导入的对象......所以你只需要将字符串写入文件(或缓冲区),然后导入它。我的另一个建议是查看ppft,它为您做了很多事情(并且不依赖于写入磁盘)。如果pfft 太低级而无法消化,则pathos.parallel 内部有一个高级接口github.com/uqfoundation/pathos/blob/master/pathos/parallel.py
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 2021-04-21
    • 2018-03-28
    相关资源
    最近更新 更多