【问题标题】:Partial Load Pickle/Cloudpickle file without required modules and classes部分加载 Pickle/Cloudpickle 文件,无需模块和类
【发布时间】:2020-07-12 01:11:50
【问题描述】:

我正在构建一个名为ML_Dash 的开源机器学习仪表板,它将训练参数保存在一个pickle 文件中,以保存用户指定的任意python 对象。这对于训练客户端加载文件很有用。

然而,仪表板提供对这些parameter.pkl 文件和其他通用pickle blob 内容的内省(想想您要转储的轨迹)。服务器的 python 环境中很可能不存在所需的 python 模块。所以我需要一种方法来检查 cloudpickle 的文件而不需要模块。

如何在没有所需模块的情况下部分加载 pickle 文件?

我尝试使用 pyCharm 的调试模式来检查失败的 cloudpickle 加载的错误跟踪和猴子补丁的位置,但似乎错误跟踪不包括 cloudpickle.load 函数内的帧。

【问题讨论】:

    标签: python pickle dill


    【解决方案1】:

    事实证明,我们可以使用来自pickle 模块的自定义Unpickler 来完成此任务!

    完整脚本如下:

    from cloudpickle import dump
    import pickle
    
    def save():
        from uvpn.maze.uvpn_e2e import UVPN
    
        agent = UVPN(graph_n=100, buffer_n=100, latent_dim=10,
                     neighbor_r=1, neighbor_r_min=0)
    
        data = dict(title="agent object",
                    count=0,
                    nested=dict(value=list(range(100))),
                    agent=agent)
    
        with open("agent.pkl", 'wb') as f:
            dump(data, f)
    
        print("done.")
    
    
    def factory(module, name):
    
        class Lie:
            def __init__(self, *args, **kwargs):
                print(args, kwargs)
                self.__d = dict()
    
            def __setitem__(self, key, value):
                self.__d[key] = value
    
            def __getitem__(self, item):
                return self.__d[item]
    
            def __call__(self, *args, **kwargs):
                print(args, kwargs)
    
            def __repr__(self):
                return f"<class '{module}.{name}'>"
    
        return Lie
    
    def read():
        from termcolor import cprint
    
        class Whatever(pickle.Unpickler):
            def find_class(self, module, name):
                try:
                    return super().find_class(module, name)
                except:
                    return factory(module, name)
    
        with open("agent.pkl", 'rb') as f:
            agent = Whatever(f).load()
    
        print(agent)
        cprint("success!", "green")
    
    
    if __name__ == '__main__':
        # save()
        read()
    

    【讨论】:

      猜你喜欢
      • 2015-02-28
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-09
      • 2014-11-08
      • 2011-03-01
      • 1970-01-01
      相关资源
      最近更新 更多