加载包含函数字典的腌制 (dill) 文件

Loading pickled (dill) file containing dictionary of functions

这是我之前提出的问题的后续问题:Loading functions in pickle file that uses class wrapper, where I wanted to pickle a dictionary of function under class wrappers,但无法加载 class 包装器模块。

我已经使用 dill 而不是 pickle 解决了这个问题:

func_dict = lowess_record()

wanted = ['func_dict', 'Interp1dPicklable', 'PolyValPicklable', 'dill', '__builtins__', 'wanted']

for name in globals().keys():
    if name not in wanted:
        del globals()[name]

del globals().wanted

with open('./func_dict.p', 'wb') as f:
    dill.dump(globals(), f)

我从 globals() 中删除了一些不必要的变量(涉及从数据创建 func_dict),因为我只想使用 func_dict,所以不需要它们。

现在当我加载腌制文件时使用:

func_dict_loaded = dill.load(open("./func_dict.p", "rb"))

我得到:

<In> func_dict_loaded.keys()

<Out> ['_dh', '__', 'dill', '_15', '__builtin__', '_i32', '_30', '_16', '_i15', quit', '_34', '_i11', '_i9', '_i8', '_i7', '_i6', '_i5', '_i4', '_i3', '_i2', _i1', '__package__', 'exit', 'get_ipython', '_i', '_i29', '_i26', '_i17', _i24', _i14', '_i22', '__doc__', '_i20', '_i16', '_i21', '_18', '_11', '_i34', __builtins__', '_ih', '_i28', 'sys', '_20', '_i27', '__name__', '___', '_i33', _', '_sh', '_i25', '_29', '_32', '_22', 'func_dict_loaded', '_i23', '_i13', _i12', '_iii', '_i10', '_13', '_12', '_ii', 'In', '_i31', '_i30', '_i19', _i18', _i35', '_oh', 'Out']

无法访问函数字典!我需要做什么才能获得预期的输出?

也许我在这里遗漏了什么,但我希望函数在 func_dict_loaded.items() 中,如果您想调用函数 _i7,那么您可以调用 func_dict_loaded['_i7']()

我已尝试重现您的问题,但避免操纵 globals()。这不是一件安全的事情。您不需要那样做来定义函数,您可以创建自己的函数。

因此,在一个会话中:

>>> import dill
>>> def myfunc():
        print("Hello world")
>>> mydict = {"myfunc": myfunc}
>>> with open (r"C:\..etc..\Temp\dict.p","wb") as f:
        dill.dump(mydict,f)

并且在另一个会话中:

>>> import dill
>>> mydict=dill.load(open (r"C:\..etc..\Temp\dict.p","rb"))
>>> mydict
{'myfunc': <function myfunc at 0x000001FC9F4C69D8>}
>>> mydict["myfunc"]()
Hello world

如您所见,降低到那种简单程度,一切正常。

我好像已经修复了,方法如下:

转储函数字典时,而不是:

dill.dump(globals(), f)

我用过:

dill.settings['recurse'] = True

with open('./Data/function_dict.p', 'wb') as f:
    dill.dump([dill, interp1d, Interp1dPicklable, PolyValPicklable, func_dict], f)
f.close()

第一行是我找到的提示here

然后,当我加载 .p 文件时,我调用:

dill.settings['recurse'] = True

func_dict_loaded = dill.load(open("./Data/function_dict.p", "rb"))

(不确定那里是否需要第一行,但它似乎没有任何危害。)

然后:

func_dict_loaded[-1]

Returns func_dict(转储时注意列表顺序)。

然后我可以使用

func_dict_loaded[-1]['func1'](x)

到 return 变量 xfunc_1 的结果。

感谢所有看过的人和 commented/answered,我希望这可以帮助以后遇到类似问题的其他人!