【问题标题】:Loading pickled (dill) file containing dictionary of functions加载包含函数字典的腌制(莳萝)文件
【发布时间】:2017-12-30 20:03:53
【问题描述】:

这是我之前提出的一个问题的后续:Loading functions in pickle file that uses class wrapper,我想在其中腌制函数 under class wrappers 的字典,但无法加载类包装器模块。

我已经使用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']

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

【问题讨论】:

  • 新用户的好帖子!
  • 谢谢@иσαнcяişтiпσ!

标签: python pickle dill


【解决方案1】:

也许我在这里遗漏了一些东西,但我希望函数位于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

如您所见,简化到这种简单程度,一切正常。

【讨论】:

  • 嗨@BoarGules,谢谢你的建议。我试过func_dict_loaded.items(),这些值只是很多字符串,或者是嵌套在另一个键中的相同键,或者是模块的文件路径。我也看不到我想要包含的任何项目,例如 func_dictInterp1dPicklablePolyValPicklable。我想我可能腌错了,但我看不出这可能发生在哪里。
【解决方案2】:

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

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

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]

返回 func_dict(转储时注意列表的顺序)。

然后我可以使用

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

为变量x返回func_1的结果。

感谢所有查看和评论/回答的人,我希望这可以帮助将来遇到类似问题的其他人!

【讨论】:

    猜你喜欢
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 2015-08-22
    • 2013-09-02
    相关资源
    最近更新 更多